mirror of
https://codeberg.org/scip/note.git
synced 2025-12-17 20:51:02 +01:00
topic, thus use "cd topicname" instead just typing "topicname"!
FIXED: there was a smal regex bug which maked it impossible to use such
topics: "4 test", in such a case note just displayed note number 4
instead of cd'ing to topic "4 test".
ADDED: a new config option "$KEEP_TIMESTAMP" allows a user to disable
note's default behavior of updating the timestamp of a note after
editing it.
1247 lines
32 KiB
SQL
Executable File
1247 lines
32 KiB
SQL
Executable File
#!/usr/bin/perl
|
|
# $Author: tom $ $Id: note.mysql,v 1.7 2000/03/08 23:11:19 tom Exp tom $ $Revision: 1.7 $
|
|
#
|
|
# $Log: note.mysql,v $
|
|
# Revision 1.7 2000/03/08 23:11:19 tom
|
|
# added cd
|
|
#
|
|
# Revision 1.6 2000/03/08 22:50:41 tom
|
|
# Added the $KEEP_TIMESTAMP option and fixed a bug regarding topic names
|
|
# and invalid resolution of them in case it started with "1 name".
|
|
#
|
|
# Revision 1.5 2000/02/25 20:59:30 tom
|
|
# corrected small timestamp problem in &edit and &new
|
|
#
|
|
# Revision 1.4 2000/02/25 13:24:11 tom
|
|
# fixed a small bug, that caused to use the last line for a note title instead the 2nd.
|
|
#
|
|
# Revision 1.3 2000/02/25 11:28:53 tom
|
|
# all changes from bin version applied to sql version
|
|
#
|
|
# Revision 1.2 2000/02/25 10:30:06 tom
|
|
# *** empty log message ***
|
|
#
|
|
#
|
|
# 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;
|
|
use strict;
|
|
use Data::Dumper;
|
|
|
|
sub usage;
|
|
sub find_editor;
|
|
sub output;
|
|
sub C;
|
|
sub uen;
|
|
sub ude;
|
|
sub num_bereich;
|
|
sub getdate;
|
|
|
|
sub new;
|
|
sub edit;
|
|
sub del;
|
|
sub display;
|
|
sub list;
|
|
sub help;
|
|
sub import;
|
|
|
|
my (
|
|
$maxlen, $timelen, $TOPIC, $TYPE, $mode, $NOTEDB,
|
|
$version, $number, $CurTopic, $CurDepth, $PATH, $CONF,
|
|
$sizeof, $MAX_TIME, $PreferredEditor, %TP, $TopicSep,
|
|
$ListType, $searchstring, $dump_file, $ALWAYS_INT, $KEEP_TIMESTAMP,
|
|
$BORDERC, $BORDER_COLOR, $_BORDERC, $NOTEC, $NOTE_COLOR,
|
|
$NUMC, $NUM_COLOR, $_NUMC, $_NOTEC, $TIMEC, $TIME_COLOR,
|
|
$_TIMEC, $TOPICC, $TOPIC_COLOR, $_TOPICC, $SetTitle, $COLOR,
|
|
$typedef, $MAX_NOTE, $MAX_TIME, @NumBlock, $ALWAYS_EDIT, $HOME,
|
|
$db, $dbname, $dbhost, $DEFAULTDBNAME, $dbuser, $USER, $dbpasswd,
|
|
$table, $fnum, $fnote, $fdate, $date
|
|
);
|
|
|
|
##################################
|
|
# define some default values.
|
|
# don't change them, instead use the config file!
|
|
|
|
$maxlen = 20;
|
|
$timelen = 22;
|
|
|
|
$date = &getdate;
|
|
|
|
$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";
|
|
$TOPIC_COLOR = "BLACK";
|
|
|
|
# Turns Topic Support on
|
|
$TOPIC = 1;
|
|
|
|
# Default topic separator: \
|
|
$TopicSep = '/';
|
|
|
|
$version = "0.7 (mysql database)";
|
|
|
|
if($TOPIC)
|
|
{
|
|
$CurDepth = 1; # the current depth inside the topic "directory" structure...
|
|
}
|
|
###################################
|
|
|
|
# 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";
|
|
my @ArgTopics = split /$TopicSep/,$ARGV[1];
|
|
$CurDepth += $#ArgTopics + 1 if $ARGV[1];
|
|
$CurTopic = $ArgTopics[$#ArgTopics]; # use the last element everytime...
|
|
$ARGV[0] = "";
|
|
}
|
|
elsif($ARGV[0] eq "-L" || $ARGV[0] eq "--longlist")
|
|
{
|
|
$mode = "list";
|
|
$ListType = "LONG";
|
|
$CurTopic = $ARGV[1];
|
|
$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] = "";
|
|
if($dump_file eq "")
|
|
{
|
|
$dump_file = "note.dump.$$";
|
|
print "not dumpfile specified, using $dump_file.\n";
|
|
}
|
|
}
|
|
elsif($ARGV[0] eq "-I" || $ARGV[0] eq "--Import" || $ARGV[0] eq "--import")
|
|
{
|
|
$mode = "import";
|
|
$dump_file = $ARGV[1];
|
|
$ARGV[0] = "";
|
|
if($dump_file eq "")
|
|
{
|
|
print "No dumpfile specified.\n";
|
|
exit(1);
|
|
}
|
|
}
|
|
elsif($ARGV[0] eq "-v" || $ARGV[0] eq "--version")
|
|
{
|
|
print "This is note $version by 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 ne "dump" && $mode ne "import")
|
|
{
|
|
$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>";
|
|
$TOPICC = "<$TOPIC_COLOR>";
|
|
$_TOPICC = "</$TOPIC_COLOR>";
|
|
|
|
|
|
|
|
if($ListType ne "LONG" && $mode ne "interactive")
|
|
{
|
|
$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 "import")
|
|
{
|
|
&import;
|
|
}
|
|
elsif($mode eq "interactive")
|
|
{
|
|
&interactive;
|
|
}
|
|
else
|
|
{
|
|
#undefined :-(
|
|
}
|
|
|
|
|
|
exit(0);
|
|
################## EOP ################
|
|
|
|
|
|
|
|
############################### DISPLAY ##################################
|
|
sub display
|
|
{
|
|
my($N,$address,$buffer,$n,$t,$match,$note,$time,$num,@row,$res);
|
|
# 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";
|
|
while(@row = $res->fetchrow)
|
|
{
|
|
output($N, $row[0], $row[1], "SINGLE");
|
|
print "\n";
|
|
$match = 1;
|
|
}
|
|
}
|
|
if(!$match)
|
|
{
|
|
print "no note with that number found!\n";
|
|
}
|
|
}
|
|
############################### SEARCH ##################################
|
|
sub search
|
|
{
|
|
my($n,$t,$match,$note,$time,$num,$buffer,@row,$res, $sqlstatement);
|
|
$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
|
|
{
|
|
my(@topic,@RealTopic, $i,$buffer,$t,$n,$num,$note,$time,@CurItem,$top,$in, $res, @row);
|
|
if($mode ne "interactive")
|
|
{
|
|
print "List of all existing notes:\n\n";
|
|
}
|
|
|
|
# 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";
|
|
if($TOPIC)
|
|
{
|
|
undef %TP;
|
|
}
|
|
|
|
while(@row = $res->fetchrow)
|
|
{
|
|
#output($row[0], $row[1], $row[2]);
|
|
$num = $row[0]; $n = $row[1]; $t = $row[2];
|
|
if($TOPIC)
|
|
{
|
|
# this allows us to have multiple topics (subtopics!)
|
|
my ($firstline,$dummy) = split /\n/, $n, 2;
|
|
if($firstline =~ /^($TopicSep)/)
|
|
{
|
|
@topic = split(/$TopicSep/,$firstline);
|
|
}
|
|
else
|
|
{
|
|
@topic = ();
|
|
}
|
|
# looks like: "\topic\"
|
|
# collect a list of topics under the current topic
|
|
if($topic[$CurDepth-1] eq $CurTopic && $topic[$CurDepth] ne "")
|
|
{
|
|
if(exists $TP{$topic[$CurDepth]})
|
|
{
|
|
$TP{$topic[$CurDepth]}++;
|
|
}
|
|
else
|
|
{
|
|
# only if the next item *is* a topic!
|
|
$TP{$topic[$CurDepth]} = 1 if(($CurDepth) <= $#topic);
|
|
}
|
|
}
|
|
elsif($topic[$CurDepth-1] eq $CurTopic || ($topic[$CurDepth] eq "" && $CurDepth ==1))
|
|
{
|
|
# cut the topic off the note-text
|
|
if($n =~ /^($TopicSep)/)
|
|
{
|
|
$CurItem[$i]->{'note'} = $dummy;
|
|
}
|
|
else
|
|
{
|
|
$CurItem[$i]->{'note'} = $n;
|
|
}
|
|
# save for later output() call
|
|
$CurItem[$i]->{'num'} = $num;
|
|
$CurItem[$i]->{'time'} = $t;
|
|
$i++;
|
|
# use this note for building the $PATH!
|
|
if($RealTopic[0] eq "")
|
|
{
|
|
@RealTopic = @topic;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
output($num, $n, $t);
|
|
}
|
|
}
|
|
if($TOPIC)
|
|
{
|
|
if($CurTopic ne "")
|
|
{
|
|
undef $PATH;
|
|
foreach (@RealTopic)
|
|
{
|
|
$PATH .= $_ . $TopicSep;
|
|
last if($_ eq $CurTopic);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$PATH = $TopicSep;
|
|
}
|
|
|
|
# we are at top level, print a list of topics...
|
|
foreach $top (sort(keys %TP))
|
|
{
|
|
output("-", " => ". $top . "$TopicSep ($TP{$top} notes)",
|
|
" Sub Topic ");
|
|
}
|
|
#print Dumper(@CurItem);
|
|
for($in=0;$in<$i;$in++)
|
|
{
|
|
output( $CurItem[$in]->{'num'},
|
|
$CurItem[$in]->{'note'},
|
|
$CurItem[$in]->{'time'} );
|
|
}
|
|
}
|
|
|
|
print "\n";
|
|
}
|
|
|
|
############################### NEW ##################################
|
|
sub new
|
|
{
|
|
my($TEMP,$editor, $time, $note, $WARN, $c, $line, $num, $te, $me, $buff,$buffer, @topic,$n,$t,$res, @row,$sqlstatement);
|
|
$time = &getdate;
|
|
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";
|
|
open E, "<$TEMP" or $WARN = 1;
|
|
if($WARN)
|
|
{
|
|
print "...edit process interupted! No note has been saved.\n";
|
|
undef $WARN;
|
|
return;
|
|
}
|
|
$c = 0;
|
|
while(<E>)
|
|
{
|
|
$_ =~ s/'/`/g;
|
|
$note = $note . $_;
|
|
}
|
|
chomp $note;
|
|
close E;
|
|
# privacy!
|
|
system "/bin/rm -f $TEMP";
|
|
}
|
|
else
|
|
{
|
|
$note = "";
|
|
$line = "";
|
|
#$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++;
|
|
if($TOPIC && $CurTopic ne "")
|
|
{
|
|
@topic = split(/$TopicSep/,$note);
|
|
if($topic[1] eq "")
|
|
{
|
|
$note = $PATH . "\n$note";
|
|
}
|
|
}
|
|
|
|
# mask all occuring \'s
|
|
$note =~ s/\\/\\\\/g;
|
|
|
|
$sqlstatement = "INSERT INTO $table VALUES ($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
|
|
{
|
|
my($i,@count, $setnum, $buff, %Merk, $num, $note, $pos, $droped, $buffer, $sqlstatement,$res, @row, $ERR);
|
|
# delete a note
|
|
&num_bereich; # get @NumBlock from $number
|
|
|
|
foreach $_ (@NumBlock)
|
|
{
|
|
$sqlstatement = "DELETE FROM $table WHERE $fnum = $_";
|
|
$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 $_ found!\n";
|
|
}
|
|
else
|
|
{
|
|
print "note number $_ has been deleted.\n";
|
|
}
|
|
}
|
|
# recount the notenumbers:
|
|
$i = 0;
|
|
$pos = 0;
|
|
$sqlstatement = "SELECT $fnum FROM $table ORDER BY $fnum";
|
|
$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 $fnum = $count[$pos]";
|
|
$db->query($sqlstatement) or die "ERROR: $Mysql::dberrstr\n";
|
|
}
|
|
}
|
|
|
|
############################### EDIT ##################################
|
|
sub edit
|
|
{
|
|
my($keeptime, $time, $editor, $TEMP, $address, $n, $buff, $c, $note, $t, $buffer, $num, $sqlstatement, $res, @row, $match);
|
|
# edit a note
|
|
$time = &getdate;
|
|
$sqlstatement = "SELECT $fnote, $fdate FROM $table WHERE $fnum = $number";
|
|
$res = $db->query($sqlstatement) or die "ERROR: $Mysql::dberrstr\n";
|
|
while(@row = $res->fetchrow)
|
|
{
|
|
$note = $row[0];
|
|
$keeptime = $row[1];
|
|
$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";
|
|
|
|
# mask all occuring \'s
|
|
$note =~ s/\\/\\\\/g;
|
|
|
|
if($KEEP_TIMESTAMP eq "YES")
|
|
{
|
|
$t = $keeptime;
|
|
}
|
|
else
|
|
{
|
|
$t = $time;
|
|
}
|
|
|
|
# we got it, now save to db
|
|
$sqlstatement = "UPDATE $table SET "
|
|
. "$fnote = '$note', "
|
|
. "$fdate = '$t' "
|
|
. "WHERE $fnum = $number";
|
|
$db->query($sqlstatement) or die "ERROR: $Mysql::dberrstr\n";
|
|
|
|
print "note number $number has been changed.\n";
|
|
}
|
|
|
|
|
|
sub dump
|
|
{
|
|
my($buffer,$num, $note, $time,$n, $t, $res, @row);
|
|
# $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";
|
|
|
|
while(@row = $res->fetchrow)
|
|
{
|
|
print STDOUT "dumping note number $row[0] to $dump_file\n";
|
|
print "Number: $row[0]\nTimestamp: $row[2]\n$row[1]\n";
|
|
}
|
|
|
|
|
|
print "\n";
|
|
close(DUMP);
|
|
select STDOUT;
|
|
}
|
|
|
|
sub import
|
|
{
|
|
my($buff, $num,$te, $me, $start, $complete, $dummi, $n, $t, $buffer, $note, $time, $date);
|
|
# open $dump_file and import it into the notedb
|
|
open (DUMP, "<$dump_file") or die "could not open $dump_file\n";
|
|
$complete=0;
|
|
$start = 0;
|
|
while(<DUMP>)
|
|
{
|
|
chomp $_;
|
|
if($_ =~ /^Number:\s\d+/)
|
|
{
|
|
if($start == 0)
|
|
{
|
|
# we have no previous record
|
|
($dummi,$number) = split(/\s/,$_);
|
|
$start = 1;
|
|
}
|
|
else
|
|
{
|
|
# we got a complete record, save it!
|
|
$db->query("INSERT INTO $table VALUES (0,'$note','$date')")
|
|
or die "ERROR: $Mysql::dberrstr\n";
|
|
print "note number $number from $dump_file inserted into notedb.\n";
|
|
$complete = 0; # restet $complete
|
|
$note = ""; # reset $note
|
|
$date = ""; # reset $date
|
|
($dummi,$number) = split(/\s/,$_);
|
|
}
|
|
}
|
|
elsif($_ =~ /^Timestamp:\s\d+/ && $complete == 0)
|
|
{
|
|
($dummi,$date,$time) = split(/\s/,$_);
|
|
$date = "$date $time";
|
|
$complete = 1;
|
|
}
|
|
else
|
|
{
|
|
$note .= $_ . "\n";
|
|
}
|
|
}
|
|
if($note ne "" && $date ne "")
|
|
{
|
|
# the last record, if existent
|
|
$db->query("INSERT INTO $table VALUES (0,'$note','$date')")
|
|
or die "ERROR: $Mysql::dberrstr\n";
|
|
print "note number $number from $dump_file inserted into notedb.\n";
|
|
}
|
|
}
|
|
|
|
|
|
|
|
sub interactive
|
|
{
|
|
my($maxlen_save, $B, $BB, $menu, $char, @LastTopic);
|
|
$maxlen_save = $maxlen;
|
|
# create menu:
|
|
$B = "<blackI>";
|
|
$BB = "</blackI>";
|
|
$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] "; # $CurTopic will be empty if $TOPIC is off!
|
|
# per default let's list all the stuff:
|
|
# Initially do a list command!
|
|
$maxlen += $timelen;
|
|
print "\n";
|
|
&list;
|
|
undef $SetTitle;
|
|
for(;;)
|
|
{
|
|
$ListType = "";
|
|
$maxlen = $maxlen_save;
|
|
if($CurDepth > 2)
|
|
{
|
|
print C $menu . $TOPICC . "../" . $CurTopic . $_TOPICC . ">";
|
|
}
|
|
else
|
|
{
|
|
print C $menu . $TOPICC . $CurTopic . $_TOPICC . ">";
|
|
}
|
|
|
|
# endless until user press "Q" or "q"!
|
|
$char = <STDIN>;
|
|
chomp $char;
|
|
if($char =~ /^\d+$/)
|
|
{
|
|
# display notes
|
|
$maxlen += $timelen;
|
|
$number = $char;
|
|
&display;
|
|
undef $SetTitle;
|
|
}
|
|
elsif($char =~ /^n$/i)
|
|
{
|
|
# create a new one
|
|
&new;
|
|
}
|
|
elsif($char =~ /^l$/ || $char =~ /^$/)
|
|
{
|
|
# list
|
|
print "\n";
|
|
$ListType = "";
|
|
$maxlen += $timelen;
|
|
&list;
|
|
undef $SetTitle;
|
|
}
|
|
elsif($char =~ /^L$/)
|
|
{
|
|
$ListType = "LONG";
|
|
print "\n";
|
|
&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!
|
|
$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
|
|
$searchstring = $';
|
|
chomp $searchstring;
|
|
&search;
|
|
}
|
|
elsif($char =~ /^s$/i)
|
|
{
|
|
# we have to ask her:
|
|
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);
|
|
}
|
|
elsif($char =~ /^\.\.$/ || $char =~ /^cd\s*\.\.$/)
|
|
{
|
|
$CurDepth-- if ($CurDepth > 1);
|
|
$CurTopic = $LastTopic[$CurDepth];
|
|
$maxlen += $timelen;
|
|
print "\n";
|
|
&list;
|
|
undef $SetTitle;
|
|
}
|
|
else
|
|
{
|
|
# unknown
|
|
my $unchar = $char;
|
|
$unchar =~ s/^cd //; # you may use cd <topic> now!
|
|
if(exists $TP{$char})
|
|
{
|
|
$char = $unchar if(exists $TP{$unchar});
|
|
$LastTopic[$CurDepth] = $CurTopic;
|
|
$CurTopic = $char;
|
|
$maxlen += $timelen;
|
|
$CurDepth++;
|
|
print "\n";
|
|
&list;
|
|
undef $SetTitle;
|
|
}
|
|
else
|
|
{
|
|
print "\nunknown command!\n";
|
|
}
|
|
undef $unchar;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
sub usage
|
|
{
|
|
print qq~This is the program note $version by Thomas Linden (c) 1999-2000.
|
|
It comes with absolutely NO WARRANTY. It is distributed under the
|
|
terms of the GNU General Public License. Use it at your own risk :-)
|
|
Usage: note [-i | --interactive] | [ options ] [ number [,number...]]
|
|
Options:
|
|
-h --help displays this help screen
|
|
-v --version displays the version number
|
|
-l --list [<topic>] lists all existing notes If no topic were specified,
|
|
it will display a list of all existing topics.
|
|
-L --longlist [<topic>] 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 --Import <file> imports a previously dumped textfile into the
|
|
note-database. Dumps from the mysql and the binary
|
|
version are in the same format.
|
|
-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.
|
|
~;
|
|
exit 1;
|
|
}
|
|
sub find_editor {
|
|
return $PreferredEditor || $ENV{"VISUAL"} || $ENV{"EDITOR"} || "vim" || "vi" || "pico";
|
|
}
|
|
#/
|
|
sub output
|
|
{
|
|
my($SSS, $LINE, $num, $note, $time, $TYPE, $L, $LONGSPC, $R, $PathLen, $SP, $title, $CUTSPACE,
|
|
$len, $diff, $Space);
|
|
# 0 = Num, 1 = Note, 2 = Time
|
|
if($ListType ne "LONG")
|
|
{
|
|
$SSS = "-" x ($maxlen + 31 - $timelen);
|
|
}
|
|
else
|
|
{
|
|
$SSS = "-" x ($maxlen + 31);
|
|
}
|
|
$LINE = "$BORDERC $SSS $_BORDERC\n";
|
|
$num = $_[0];
|
|
$note = $_[1];
|
|
$time = $_[2];
|
|
$TYPE = $_[3];
|
|
$L = $BORDERC . "[" . $_BORDERC;
|
|
$LONGSPC = " " x (22 + 3);
|
|
$R = $BORDERC . "]" . $_BORDERC;
|
|
$PathLen = length($PATH); # will be ZERO, if not in TOPIC mode!
|
|
if($TYPE ne "SINGLE")
|
|
{
|
|
if(!$SetTitle)
|
|
{
|
|
$SP = "";
|
|
# print only if it is the first line!
|
|
if($ListType ne "LONG")
|
|
{
|
|
$SP = " " x ($maxlen-2 - $timelen - $PathLen);
|
|
}
|
|
else
|
|
{
|
|
$SP = " " x ($maxlen-2 - $PathLen);
|
|
}
|
|
print C $LINE;
|
|
|
|
print C "$L $NUMC#$_NUMC ";
|
|
if($ListType eq "LONG")
|
|
{
|
|
print C " $TIMEC" . "creation date$_TIMEC ";
|
|
}
|
|
else
|
|
{
|
|
print $LONGSPC;
|
|
}
|
|
if($TOPIC)
|
|
{
|
|
print C $TOPICC . "$PATH $_TOPICC$SP$R\n";
|
|
}
|
|
else
|
|
{
|
|
print C $NOTEC . "note$_NOTEC$SP$R\n";
|
|
}
|
|
|
|
print C $LINE;
|
|
$SetTitle = 1;
|
|
}
|
|
$title = "";
|
|
$CUTSPACE = " " x $maxlen;
|
|
$note =~ s/\n/$CUTSPACE/g;
|
|
$len = length($note);
|
|
if($len < $maxlen-3)
|
|
{
|
|
$diff = $maxlen - $len;
|
|
$Space = " " x $diff;
|
|
if($num eq "-")
|
|
{
|
|
$title = $BORDERC . $TOPICC . "\"" . $note . "\"" . $_TOPICC . $Space . "$_BORDERC";
|
|
}
|
|
else
|
|
{
|
|
$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;
|
|
$Space = " " x ($maxlen - 16);
|
|
$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
|
|
{
|
|
my(%Color, $default, $S, $Col, $NC, $T);
|
|
# \033[1m%30s\033[0m
|
|
%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
|
|
{
|
|
my($T);
|
|
$T = pack("u", $_[0]);
|
|
chomp $T;
|
|
return $T;
|
|
}
|
|
|
|
sub ude
|
|
{
|
|
my($T);
|
|
$T = unpack("u", $_[0]);
|
|
return $T;
|
|
}
|
|
|
|
sub num_bereich
|
|
{
|
|
my($m,@LR,@Sorted_LR,$i);
|
|
# $number is the one we want to delete!
|
|
# But does it contain kommas?
|
|
$m = 0;
|
|
if($number =~ /\,/)
|
|
{
|
|
# accept -d 3,4,7
|
|
@NumBlock = split(/\,/,$number);
|
|
}
|
|
elsif($number =~ /^\d+\-\d+$/)
|
|
{
|
|
# accept -d 3-9
|
|
@LR = split(/\-/,$number);
|
|
@Sorted_LR = ();
|
|
|
|
if($LR[0] > $LR[1])
|
|
{
|
|
@Sorted_LR = ($LR[1], $LR[0]);
|
|
}
|
|
elsif($LR[0] == $LR[1])
|
|
{
|
|
# 0 and 1 are the same
|
|
@Sorted_LR = ($LR[0], $LR[1]);
|
|
}
|
|
else
|
|
{
|
|
@Sorted_LR = ($LR[0], $LR[1]);
|
|
}
|
|
|
|
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 getdate
|
|
{
|
|
my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
|
|
$year += 1900;
|
|
$mon += 1;
|
|
$mon =~ s/^(\d)$/0$1/;
|
|
$hour =~ s/^(\d)$/0$1/;
|
|
$min =~ s/^(\d)$/0$1/;
|
|
$sec =~ s/^(\d)$/0$1/;
|
|
$mday =~ s/^(\d)$/0$1/;
|
|
return "$mday.$mon.$year $hour:$min:$sec";
|
|
}
|
|
|
|
|
|
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 note
|
|
a time.~;
|
|
if($TOPIC)
|
|
{
|
|
print qq~
|
|
T print a list of all existing topics. You can change the actual
|
|
topic by simply typing it's name. You can create a new topic by
|
|
creating a new note, the first line must be the topic borderd by
|
|
backslashes, i.e.: "\\newtopic\\". If you type just ".." instead
|
|
of a topic, you will go to the "default" topic, which contains
|
|
all notes without a topic.~;
|
|
}
|
|
print qq~
|
|
?/H This help screen.
|
|
Q Exit the program.
|
|
|
|
All commands except the List command are case insensitive.
|
|
---------------------------------------------------------------
|
|
~;
|
|
}
|