13 Commits

Author SHA1 Message Date
33d5015483 moved to codeberg 2025-12-15 20:46:15 +01:00
T. von Dein
9dc71d1885 moving to codeberg (#13) 2025-12-15 20:45:06 +01:00
4f06a9f8f5 STDIN related fixes
- fixed https://rt.cpan.org/Ticket/Display.html?id=155578: adding a
new entry from STDIN now works regardless of interactive seting.

- added new flag -n

- fixed note number argument

- code reorganized
2024-09-24 18:40:13 +02:00
bb5779a664 added latest changes 2024-09-05 18:10:15 +02:00
dbaf515259 Fix https://github.com/TLINDEN/note/issues/11:
- rewrite documentation sections regarding database backends.
- add depcreation announcement to README
- enhanced default config to reflect the new default file extensions
- enhanced error message when Encryption is set to off but a binary
  file is being encountered.
- bump version to 1.4.1
2024-09-05 17:55:08 +02:00
891f830cba Fix confusion of new users regarding db files.
Now, we're using a different file extension for every db file
type. That way, if the user tries another file type and forgets to
specify a filename, the default is NOT to use the same one as before,
but another file. That way the message "file is encrypted" will not
appear anymore, if a new user follows the above steps.
2024-09-05 17:17:36 +02:00
37e73950da added JSON export format:
Starting with version 1.4 JSON export format will be supported but
not be enabled by default. However a deprecation notice will appear if
a user still uses YAML format. YAML support will be removed in version
1.5.

Fixes https://github.com/TLINDEN/note/issues/10.
2023-08-13 19:05:29 +02:00
1b842625ed syncer enhancements:
- if two entries of the same title exist in both exported databases,
show a diff and ask the user which one to use (or both).

- write the result directly to a file.
2023-08-13 11:49:45 +02:00
c03d521b2c fixed-newlines 2023-08-12 20:24:18 +02:00
53c16708fe Added script to recombine 2 dumps into a new one." 2023-08-11 20:15:36 +02:00
T.v.Dein
4505ec70a4 Merge pull request #8 from eamanu/fix-new-spelling
[WIP] fix-spelling
2019-06-05 15:55:44 +02:00
Emmanuel Arias
c5cdc42445 more fix 2019-05-09 01:09:12 +00:00
Emmanuel Arias
ec2a36b4ad fix-spelling
Fix spelling on several filesIndex: note/lib/NOTEDB/README

Gbp-Pq: Name 0001-fix-spelling.patch
Signed-off-by: Emmanuel Arias <emmanuelarias30@gmail.com>
2019-05-09 01:06:37 +00:00
27 changed files with 216 additions and 7405 deletions

637
Changelog
View File

@@ -1,637 +0,0 @@
================================================================================
1.3.26: fixed installer, on newer perls NOTEDB/* is being ignored
================================================================================
1.3.25: fixed indents
================================================================================
1.3.24: removed bashism in mysql installer.
================================================================================
1.3.23: defect distritbution. do not use.
================================================================================
1.3.22: fixed bug in mysql backend.
added retry feature for NOTEDB::pwsafe3 backend save() password
entering. bails out after 5 retries.
================================================================================
1.3.21:
Changed note id generation in NOTEDB::pwsafe3::_uuid(), again.
Instead of crc checksums and the loop to avoid duplicates, I just
use a counter and sort the entries by ctime, so that older entries
keep their note id. Also this should fix a rare bug, where the
code hangs because of said loop.
================================================================================
1.3.20:
fixed bug in NOTEDB::pwsafe3::_retrieve(), it iterated over the
records unsorted which resulted in different note ids each time
the program runs.
================================================================================
1.3.19:
revert fix in NOTEDB::pwsafe3::filechanged(), use > again.
================================================================================
1.3.18:
fixed unit tests and added more (lots of them)
fixed several bugs in backend modules, which I found during
writing of the unit tests.
================================================================================
1.3.17:
applied patch by Bill Carlson, which fixes string length issues
in non-interactive search mode.
fixed usage text (-h) so that it now contains the available
options.
================================================================================
1.3.16:
fixed checking of encrypted notes when encryption is turned off.
instead of checking note id 1, we now check the first entry,
whatever id it may have.
================================================================================
1.3.15:
fixed bug in NOTEDB::pwsafe3 backend, it converted the date
of a note entry into the wrong formatted timestamp.
================================================================================
1.3.14:
fixed bug in NOTEDB::pwsafe3 backend, it used lockging on the
database file for reading, which is wrong.
================================================================================
1.3.13:
ADDED: new config parameter 'motd', a note entry which will be shown
on startup (if exists).
CHANGED: the prompt will now show if the current instance is running
in readonly mode.
================================================================================
1.3.12:
FIXED: NOTEDB::general data backend module did overwrite records if
there were some deleted ones in the database.
================================================================================
1.3.11:
FIXED: NOTEDB::pwsafe3 contained the old python stuff in delete code.
================================================================================
1.3.10:
FIXED: the YAML export/import change were missing too. grml...
FIXED: NOTEDB::general backend fixed loading Config::General
================================================================================
1.3.9:
FIXED: bin/note were missing. for whatever reason, I don't know.
================================================================================
1.3.8:
ADDED: New backend added: NOTEDB::pwsafe3, which adds support to store
notes in a Password Safe v3 database.
FIXED: -d didn't work, because of a typo in mode assignment.
================================================================================
1.3.7:
ADDED: added ticket feature, which adds a unique id to each
new note, which persists during imports/exports. the
id is a randomly generated string.
================================================================================
1.3.6:
ADDED: Added test cases for "make test"
ADDED: Added test for optional and required perl modules in
Makefile.PL
FIXED: NOTEDB::dumper version string were wrong, therefore
cpan didn't index is properly.
================================================================================
1.3.5:
FIXED: Applied patch by Elmar Loos which fixes misbehavior for
-t and -T (identical output)
FIXED: Fixed import bug which omitted the timestamp of the last
entry, supmitted by Bill Barnard.
FIXED: Fixed another import "bug" (or design flaw) which caused
imported notes to get new numbering after importing them.
Submitted by Bill Barnard.
CHANGED: Until 1.3.4 missing Crypt:: modules lead to unencrypted
fallback by note. From 1.3.5 on this will no more happen,
it croaks now until you install the desired modules
or modify your configuration to use no encryption.
CHANGED: default config and default settings without config have
been changed. They are now simpler, no colours or anything
so that it works better out of the box in any terminal
window or shell (e.g. on dark ones or the like).
ADDED: New interactive mode command: "c". It is now possible to
change note's behavior at runtime. No database related
parameters can be modified.
================================================================================
1.3.4:
ADDED: Each note now contains a "ticket number" which identifies
it against other notes. Those tickets are not changing when
notes will be reorganized.
ADDED: added support for less to view note entries instead of
just printing it to STDOUT. (interactive mode).
================================================================================
1.3.3:
ADDED: new configfile parameter PrintLines (default: YES), which
controls wether listings are separated by horizontal lines.
================================================================================
1.3.2:
FIXED: NOTEDB::mysql backend parameter fixed (dbtype)
FIXED: NOTEDB::mysql didn't fetch topics correctly
FIXED: NOTEDB::text didn't correctly return last highest note id
================================================================================
1.3.1:
FIXED: most config variables not related to drivers had
invalid sentence in note, so the new ones of the new config
were ignored.
FIXED: added version to NOTEDB::text.
FIXED: fixed handling of NOTEDB::crypt_supported, now encryption
works again.
ADDED: NOTEDB::text now supports internal caching too.
CHANGED: lock() sets the umask internally to 022, so that other
users are able to read the lockfile.
================================================================================
1.3.0:
ADDED: new config option: ReadOnly
ADDED: new database backend: NOTEDB::text, which uses the Storable
module.
CHANGED: the data import will now written to db once.
CHANGED: added global database locking support, which is usually
useful in multiuser environments.
ADDED: new database backend: NOTEDB::general, which uses the
Config::General module.
CLEANUP: almost everywhere
CHANGED: noterc config format changed! especially the config for
backend drivers has changed a lot.
CHANGED: the configuration variables are now stored in a hash, this
saved some global variables, the driver variables are stored
in an extra hash, which contains one key per driver, this
hash gets supplied to the driver backend module 1:1.
CHANGED: the libpath variable has been removed, it didnt't work either.
use now .. instead, so that a local installation for a non
root user is still possible.
================================================================================
1.2.6:
FIXED: the binary driver (NOTEDB::binary) encounters now if a note
entry is bigger then MaxNoteByte. It prints the overlapping
part to STDERR, and a warning message and finally saves
the complete, unchanged note entry to an external text file.
================================================================================
1.2.5:
FIXED: removed any file/path actions using '/'. replaced by portable
functions by using File::Spec. This makes it possible to run
note unchanged on win32 (and possibly any other) environments.
FIXED: added a whitespace to the prompt in interactive mode to
circumvent a bug in the win32 Term::ReadLine module which causes
the cursor to be displayed on the left side (column 0) of
the screen.
FIXED: added "or die" code to some commands which are running inside
an eval{} block to fetch errors. Without the "or die"s no
error could ever catched.
CHANGED: removed HOME variable support of the noterc. in fact, if it
exists, no error will occur, but it will no longer be used.
It didn't work in older versions anyway.
ADDED: It is now possible to quit note using CTRL-D (or: EOF)
================================================================================
1.2.4:
CHANGED: in the function find_editor() the alternatives vim and pico
has been removed because they would never had a match.
FIXED: applied patch by Bill Barnard <bill@barnard-engineering.com>
which fixes a bug in the sub format() which features bold
hidden or underlined text. Now its possible to use a ^ char
in hidden texts too. I applied the same for the other regexps.
ADDED: if the config variable FormatText is set to 'simple' then
only one * _ { or / will make the text tagged with them to
be displayed formatted, instead of two.
ADDED: added Term::ReadLine support (auto-completion and history).
================================================================================
1.2.3:
ADDED: if FormatText is enabled one can now use a new special format
tag: //. If a text is surrounded by two slashes, i.e.: //blah//
then it appears "invisible" by using blue forground and blue
background color for displaying. This is handy for passwords
since no nobody can grab you password by looking at your
monitor, but you can copy&paste it.
================================================================================
1.2.2:
FIXED: oneliner note entries caused breaked displaying in interactive
mode.
FIXED: list displaying in interactiv mode corrected. the width of the
note number will now correctly used.
CHANGED: the default setting of note will now be to use an external
editor instead of stdin.
CHANGED: the unneccessary apostrophes in listings has been removed.
ADDED: the note version will be displayed in the titlebar of interactive
mode.
ADDED: new config variable AutoClear, which is turned on by default,
which controls wether the screen shall be cleared after each
item (display, list and so on).
================================================================================
1.2.1:
CHANGED: added the correct installation instructions to the README file.
REMOVED: removed the usage guidelines from te README file. This information
were redundant because its also contained in the manpage.
FIXED: on FreeBSD the setting of MaxLen to 'auto' had no effect because the
output of 'stty -a' which I use in note to determine the actual
size of the terminal, is different from that on linux.
ADDED: topics can now be abbreviated in interactive mode, which
avoids typing. abbreviation works only if an explicit
match could be found, otherwise the available topics that
matches will be suggested.
================================================================================
1.2.0:
CHANGED: using Makemaker instead of self-written code in Makefile.PL
for installation. No more dependency checks built-in because
note runs out-of-the-box without additional modules, as a matter fact.
ADDED: if a search matches exactly on one note it will be displayed
directly, which avoids typing.
CHANGED: the main if-else contruct for calling the several subs has
been replaced by a simple closure call.
CHANGED: notes will now displayed in a slightly simpler fashion in interactive
mode, without the separator line between the title and the note.
ADDED: note can now determine automatically the width and height of
the terminal window it runs in (in interactive mode only) and
sets the width/height of what it prints accordingly. the config
variable "MaxLen" must be set to "auto" (which is the default
from now on) to get this to work.
ADDED: any interactive command will now clear the screen before it does
anything. this look much more uncluttered.
ADDED: if multiple notes are printed at once (i.e. note 1,2) then the
separator line between them will no more being printed because
every notes title is preceded by a line anyway.
CHANGED: by default the default operation mode is now interactive mode,
which is somewhat kindlier to new users.
CHANGED: changed to order which editor note tries to find. vi got now
higher precedence, because it is likely installed on almost
any unix system.
CHANGED: cosmetics.
NOTE: increased minor version number from 1 to 2 to indicate that
development begun after 2 1/2 years pause again :-)
================================================================================
1.1.2:
FIXED: Empty notes will no longer stored.
ADDED: A new config option which allows you to specify a time format
other than the default one which is used by note.
================================================================================
1.1.1:
FIXED: Some odd typos in README and note.pod.
FIXED: if ShortCd was on and one used "cd 3" and after that "cd .."
then the current topic was wrong (empty $PATH).
FIXED: if the current topic contained no notes and one created a new
note without specifying a topic, then note did not add a
proper topic (also because of empty $PATH).
CHANGED: the default colors are now visible both on black and white
backgrounds, see next entry.
ADDED: two more color values: <white_black> and <bold>.
CHANGED: the color hash is now in ::main instead of ::C.
================================================================================
1.1.0:
CHANGED: does no more use the external touch command to create a new
file, use perls open() instead.
CHANGED: excluded some of the help texts from the usage message and the
interactive help command to a manpage.
ADDED: new commandline flag "--encrypt" which one can use to encrypt
the mysql database password. This will be decrypted before
connecting to the db. There is also a new config file option
"encrypt_passwd" which indicates an encrypted db-password.
ADDED: another new config option "ShortCd", which can be set to "yes"
or 1 and if set, then a command like "cd 13" would jump
directly to the topic of the note with the number 13.
ADDED: now you can at any time cd back to the "root" of the
topic-structure using the command "cd /".
CHANGED: mysql.pm does now only do a table-lock on single write
accesses, no more on the whole session. This allows one to
access the same db twice or more.
FIXED: Changed README and Changelog for readability on 80 by 25
displays. And changed indentation of the note script itself.
ADDED: NOTEDB.pm - a generic module, which holds some methods, which
are used by binary.pm, mysql.pm and dbm.pm.
ADDED: NOTEDB.pm generate_search(), which allows one to
use AND, OR and various combinations of them using ( and ).
ADDED: a search does now return the 2nd line of a note if a matching
note's first line is a topic.
CHANGED: use "unshift" instead of push to add $libpath to @INC.
ADDED: a new feature, Caching of notes. supported by binary.pm and
mysql.pm. To turn it on, one need to set "Cache" in the config
to a true value.
CHANGED: oop-ized and re-indented the modules dbm.pm, mysql.pm and
binary.pm.
ADDED: You can now specify a port for the mysql backend ("DbPort").
================================================================================
1.0.9: jumped directly to 1.1.0, too many additions.
================================================================================
1.0.8:
FIXED: typo in noterc shipped with package may caused confusion
(BLOWFISH instead of Blowfish).
CHANGED: changed the way note manages temporary filez. It uses now a
random string instead of just it's own PID. It does also change
it's umask to 077 and, if applicable (on ext2 filesystems)
issues "chattr +s" which will cause the ext2 inodes to be
zero'd after file deletion.
ADDED: A new config option allows the user to specify her own
temp-directory. The default is still /tmp.
================================================================================
1.0.7:
FIXED: there was a bug in the search expression, use now \Q and \E.
ADDED: --config <file> allows one to use another config than the
default.
================================================================================
1.0.6:
FIXED: there were some odd bugs in commandline parsing, some options
were unavailable.
FIXED: Forgot "PreferredEditor" config-option in the new config format.
FIXED: the interactive "cd .." command has ignored the presence of a
"DefaultLong" setting(and search too)... thx to Peter.
CHANGED: Optimized a little bit the output routine, now it is better to
read.
ADDED: sub format and appropriate config-option for text formatting
capabilities.
CHANGED: changed getconfig regexp, which allows now also to use
Option = Param.
FIXED: was not possible to override config-options, which are set by
default to something.
ADDED: note checks now, if a database os actually really encrypted and
exits with an error if it s and the user turned off encryption.
This protects her from destroying it's own database ..
================================================================================
1.0.5:
FIXED: the T (and t respectively) printed nothing out since 1.0.3!
It does it now again...
ADDED: a new database backend added, NOTEDB::dbm, which uses DBM
files for storage.
FIXED: &display-tree returns now, if there is no note, otherwise it
would die because of an undefined refernce.
CHANGED: Changed the config file format completely. It is now no more
a perl file, instead it is a simple plain text file which note
parses.
CHANGED: Changed the way, note loads it database backend. It uses now
the $dbdriver variable as module-name, which makes it possible
easily to write your own backend without the need to change
note itself.
FIXED: Removed Getopt::Long option "bundling", causes errors with perl
5.6.0 and is not senceful.
FIXED: Added the Getopt::Long option "no_ignore_case". In 1.0.4 options
were case insensitive causing -i to be interpreted as --import
instead of --interactive ;-(((
Thanks to Peter Palmreuter for the following fixed/additions:
ADDED: a new config option $DEFAULT_LIST, which causes note,
if turned to "LONG", to use long-listing as default.
But it will still be able to use short-listing if you
explicit specify that.
FIXED: sub search prints now an appropriate error-message in
case no searchstring was given instead of jumping to
usage.
CHANGED: Changed the text in the interactive help to reflect
changes of verion 1.0.3 (t and T).
================================================================================
1.0.4:
CHANGED: Moved from @ARGV-parsing to Getopt::Long, adding options is now
much easier and I do now understand my own code ;-)
ADDED: --raw, the "Raw Mode", which turns off any formatting of output.
================================================================================
1.0.3:
ADDED: "-" works also for --dump, but in the other direction. It causes
note to dump to standard output instead into a file.
ADDED: you can specify - as filename for use with --import and if you
want to create a new note. "-" stands for standardinput and
it allows you to pipe another commands output to note!
ADDED: you can now use an environment variable for the passphrase
(when using encryption). If it is present, note will not ask
for a passphrase. This is very useful in comination with the
addition above, for use in scripts.
CHANGED: the interactive help screen is now coloured.
ADDED: -o commandline switch, which causes note to overwrite an
existing database when importing data from a previous dump.
Very handy if you want to re-initialize your db, i.e. if you
changed the format.
ADDED: the long-tree-view (-T) displays now also the note-number of
each note.
================================================================================
1.0.2:
ADDED: Topic-Tree overview command (-t or -T).
ADDED: Enhanced list command in interactive mode, you can now specify
a topic which notes you want to see.
CHANGED: updated the help and usage sections to reflect the additions
above.
================================================================================
1.0.1:
FIXED: fixed bug in NOTEDB::mysql, which caused note to store NULL
values in db, if encryption was off. A really dump failure :-(
================================================================================
1.0.0:
CHANGED: removed install.sh. use now a Makefile for installation.
ADDED: Encryption support. Note can now encrypt notes using IDEA
or DES as encryption-protocols(symetric).
================================================================================
0.9:
FIXED: There were many new bugs after my last changes *grrrrr*. fixed.
Works now properly, with both backends!
FIXED: and another bug: recounting of numbers did not take care about
the existing order! If you deleted note #12, then note #13
became not neccessarily #12! Instead it becames any other
number (kind of randomly...).
CHANGED: NOTEDB::binary set_del function changed, it does no more require
a temporary file for number recount. Instead it uses get_all and
stores all notes in RAM and then rewrites the database.
FIXED: fixed the set_new call within note. It used 0 as the first param
(number) which is not useful since we dont have support for
autoincrement from all database backends.
FIXED: fixed the function set_recountnum in NITEDB::mysql, it was also
incorrect :-((( 0.8 seemed to be a very bad early alpha...
FIXED: there was a bug in NOTEDB::binary which caused not to recount
note numbers after deleting one :-(
================================================================================
0.8:
ADDED: NOTEDB::binary. so now 0.8 is ready for shipping !
FIXED: regexp bug fixed. It was only possible to delete 2 items
together
separated by comma ("d 1,2,3,4" deleted only 1,2!).
ADDED: Some new config options which reflects the new module structure.
So you can change your database backend without the need to
replace the note script itself.
FIXED: the previously added feature "cd <topic>" didn't really work :-(
ADDED: NOTEDB::mysql added. Perlmodule, which I will use within
note from now on instead of buildin functions for accessing the
database. From now on I only need to maintain one version of
note, since the module interface will be identical between the
bin and sql version.
CHANGED: The SQL code does not use Mysql.pm anymore. Instead it is coded
using the more portable DBI module. This allows one easily to
switch to anther database, which is supported by DBI.
CHANGED: Locking. The db-table will now be locked before note accesses
it.
FIXED: width of listings is now always the same independent of the
stringlength of a certain note.
================================================================================
0.7:
ADDED: one can now use the unix-like "cd" command to change to another
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.
================================================================================
0.6:
FIXED: oops - the new suptopic feature confused the commandline-mode of
note! quickly corrected! so subtopics also available from
commandline.
FIXED: a small bug fiyed, it was impossible to use -D or -I from
commandline, if $ALWAYS_INT was turned on, now it is.
FIXED: fixed problem with local/global variable $time, which confused
the script under certain circumstances, now $time is no more
global, it will be read in (using &getdate) locally by &new
and &edit.
CHANGED: The Topic separator is no longer hardcoded, one can customize
it using the $TopicSep variable, the default is now /, the
backslash will no more work!
CHANGED: use perl buildin localtime() function instead of
GNU date, which is possibly not installed on every target
system (i.e. win32), therefore better portability!
CHANGED: use now the strict module
ADDED: Support for subtopics added (and sub-sub-..-topics).
CHANGED: Removed the "T" command, it is now obsolete.
CHANGED: behavior of list command changed, now shows topics as well as
notes under the current topic(if there are some).
CHANGED: The ".." command takes you now one level higher in your topic-
structure.
ADDED: A new config option $PreferredEditor, which you can use to
specify your own choice of editor.
FIXED: A bug at line 769 causing single note where smaller than note-
listings
================================================================================
0.5:
ADDED: Topic support(requested). You can sort the various notes under
different topics now.
FIXED: There was another bug, which caused the list command to display
the notes with a too high value of $maxlen.
================================================================================
0.4.2:
ADDED: If run in interactive mode, note will at first do a list
command.
FIXED: A bug caused note to save bogus timestamps after editing a note.
CHANGED: It does no more print 3 newlines before the menu in interactive
mode.
FIXED: Some more vars will be resetted during each loop in interactive
mode. $ListType.
================================================================================
0.4.1:
ADDED: The install.sh script for the mysql version is no able to
install the required Mysql module directly from CPAN, thanks
to David A. Bandel!
FIXED: The mysql version did not display notes (i.e.: "note 3" did
nothing)
CHANGED: Again, the sql-format of the mysql database has been changed.
Now there are only 3 fields, the number filed is the primary
key, the id field in previous versions was a waste of
diskspace...
CHANGED: The format of the dump-output has been changed.
ADDED: It is now possible to import previously dumped notes into the
notedb
(dumps from both versions are compatible with each other)
FIXED: the function num_bereich() had a bug, which caused ot to ignore under
some circumstances one number (i.e. "note -d 4-13" did nothing).
================================================================================
0.4:
CHANGED: ok, mysql support is back again (upon requests). therefore there
are two different version of the script in the same time with
the same features, one for mysql and the other one for the
binary database.
ADDED: Dump to textfile capability. Later on I want to dump it into a
palm readable format, any help is welcome!
ADDED: interactive mode.
CHANGED: Better modularity, better code.
CHANGED: note can now run without the need of a config file. If does not
exist, it will try to work with default values.
ADDED: sub num_bereich(), which allows one to specify more then one
number for deletion or displaying (i.e.: "-d 1,4,7" or "-d 4-9")
================================================================================
0.3:
CHANGED: it uses no more a mysql database, but a binary file instead.
This is much faster!
ADDED: note can display the notes with colors, it is turned off by
default
================================================================================
0.2:
FIXED: now any occurence of ' will be masked with \' before storage
to the mysql database.
FIXED: now numbers of notes will be recounted, if one delete one note,
so the list of notes will everytime start with 1,2,3,...
CHANGED: the look of the list output has been changed, similar to a table
================================================================================
0.1:
INITIAL RELEASE.

View File

@@ -1,28 +0,0 @@
MANIFEST
bin/stresstest.sh
bin/note
mysql/permissions
mysql/sql
mysql/install.sh
mysql/README
VERSION
config/rc
config/noterc
README
UPGRADE
note.pod
TODO
t/run.t
lib/NOTEDB/mysql.pm
lib/NOTEDB/text.pm
lib/NOTEDB/dumper.pm
lib/NOTEDB/pwsafe3.pm
lib/NOTEDB/dbm.pm
lib/NOTEDB/README
lib/NOTEDB/binary.pm
lib/NOTEDB/general.pm
lib/NOTEDB.pm
Changelog
Makefile.PL
META.yml
META.json

View File

@@ -1,41 +0,0 @@
use ExtUtils::MakeMaker;
my %optional = (
'Crypt::CBC' => "Required by encryption support",
'Crypt::Rijndael' => "Required by encryption support",
'Data::Dumper' => "Required by dumper DB backend",
'MIME::Base64' => "Required by varios optional backends",
'Storable' => "Required by text DB backend",
'Config::General' => "Required by general DB backend",
'DB_File' => "Required by dbm DB backend",
'DBI' => "Required by mysql DB backend",
'DBD::mysql' => "Required by mysql DB backend",
'Crypt::PWSafe3' => "Required by Password Safe v3 backend"
);
foreach my $module (sort keys %optional) {
eval "require $module";
if ($@) {
warn("Optional module $module not installed, $optional{$module}\n");
}
}
WriteMakefile(
'NAME' => 'note',
'VERSION_FROM' => 'bin/note', # finds $VERSION
'EXE_FILES' => [ 'bin/note' ],
'PREREQ_PM' => {
'IO::File' => 0,
'FileHandle' => 0,
'File::Spec' => 0,
'File::Glob' => 0,
'FileHandle' => 0,
'Getopt::Long' => 0,
'Fcntl' => 0,
'IO::Seekable' => 0,
'YAML' => 0,
},
($ExtUtils::MakeMaker::VERSION ge '6.31'? ('LICENSE' => 'perl', ) : ()),
'clean' => { FILES => 't/*.out t/test.cfg *~ */*~' }
);

217
README
View File

@@ -1,217 +0,0 @@
note 1.3.20 by T.v.Dein (09/02/2015)
=======================================
Introduction
============
This is a small console program written in
perl, which allows you to manage notes similar
to programs like "knotes" from commandline.
There are currently three different database backends,
which you can use with note:
o NOTEDB::binary - this is the default backend
and uses a binary file to store your notes.
o NOTEDB::mysql - this backend uses a mysql
database to store your notes. You can switch
easily to another DBMS since this module uses
the Perl standard module "DBI" for database-
access. See below for more info on this topic!
o NOTEDB::dbm - this module uses two DBM files
for data storage and requires the module DB_FILE,
which is part of the perl standard distribution.
See below for more details about the DBM module.
o NOTEDB::general - uses the module Config::General
for storage, which makes the data file portable,
since it is a plain ascii file (binary content
will be base64 encoded).
o NOTEDB::text - uses the Storable module for data
storage (a serializer). Storable is included with
perl, and since it's written in C, it's very fast.
But the resulting data files are not that portable
as the once of NOTEDB::general are.
Where to get?
=============
By now you can download it at http://www.daemon.de/NOTE.
If you are using debian, you can apt-get it. If you are
using gentoo, you can emerge it.
You may also try your nearest tucows or freshmeat mirror.
Features
========
o Several different database backends, mysql(DBI), dbm,
binary(bin file), general and text (text files).
o Commandline interface using the standard perl module
Getopt::Long, which allows you to use short or long
command-line options.
o Interactive interface(pure ascii), the following functions
are available in interactive mode: list, display, topic,
delete, edit, help.
o Highly confiurable using a perlish configfile ~/.noterc.
although it is configurable it is not required, note can
run without a configfile using useful default presets.
o Colourized output is supported using ASCII Escape-Sequences.
o The user can customize the color for each item.
o Data can be stored in various different database backends,
since all database access is excluded from the program itself
in perl modules.
o Notes can be deleted, edited and you can search trough your notes.
o Notes can be categorized. Each category(topic) can contain multiple
notes and even more sup-topics. There is no limitation about
sub topics.
o You can view all notes in a list and it is possible only to view
notes under a certain topic.
o There is a tree-view, which allows you to get an overview of your
topic-hierarchy.
o Notes can be encrypted using DES or IDEA algorythms and Crypt::CBC.
o You can dump the contents of your note database into a plain text
file, which can later be imported. Imports can be appended or it can
overwrite an existing database (-o).
o Note has scripting capabilities, you can create a new note by piping
another commands output to note, you can also import a notedump from
stdin as well es duming to stdout instead a file. Additional, there
is an option --raw available, which prints everything out completely
without formatting.
o for better performance, note can cache the database for listings
or searching.
o It can be installed without root-privileges.
o if Term::ReadLine (and Term::ReadLine::Gnu) is installed, history
and auto-completion are supported in interactive mode.
o Last, a while ago a user stated: "... it simply does, what it
says ..."
Requirements
============
You need the following things:
o perl installed (5.004x)
o The module IO::Seekable and Fcntl, which should be
already installed with your perl distributuion if
you want to use the binary database backend.
o DBI module and DBI::mysql if you want to use the
mysql database backend.
o The module DB_FILE if you want to use the DBM module.
o Getopt::Long (part of perl std ditribution)
o Term::ReadLine and optionally Term::ReadLine::Gnu if
you want to use the auto-completion and history functionality.
o Config::General if you want to use the NOTEDB::general
backend.
Installation
============
Unpack the tar-ball and issue the following command:
$ perl Makefile.PL
This creates the Makefile neccessary for installing.
You may add some additional variables to the commandline, the
most important one is PREFIX.
Then enter the following command to prepare the installation
process:
$ make
After that, you are ready to install. Become root and issue:
# make install
The installation process installs all modules for every available
data backends. The default note configuration does not require
additional perl modules.
If you want to use the mysql backend refer to the installation
instructions for the mysql database installation in mysql/README.
If you want to use encryption support, you will need at least
Crypt:CBC and Crypt::Blowfish (or Crypt::DES or whatever).
Configuration
=============
This version of note doesn't neccessarily need
a configuration file. But you can have one and change
some default values. Take a look to the file config/noterc
provided with this tarball. There are detailed instructions
about every available parameter.
Simply copy this file into your home-directory and name it
.noterc
If you decide not to use the default database backend (a binary
file), you will *need* a configuration!
Usage
=====
Refer to the note(1) manpage for usage instructions.
Comments
========
You can send any comments to Thomas Linden <tom at linden dot at>.
If you find a bug or if you have a suggestion for improvement of the
script feel free to send me a patch ;-)
License
=======
This program comes with absolutely NO WARRANTY. It is distributed under
the terms of the GNU General Public License. Use it at your own risk :-)
You can read the complete GPL at: http://www.gnu.org/copyleft/gpl.html
Recources
=========
The command-line options and all commands of the interactive mode are
described in the supplied note(1) manpage.
You may also refer to the note website http://www.daemon.de/note/.
Author and Copyright
====================
The author is T.v.Dein
note is Copyright of T.v.Dein
Contributors / Credits
======================
Shouts to all those guys who helped me to enhance note: THANKS A LOT!
Jens Heunemann <jens.heunemann@consol.de> - sub tree.
Peter Palmreuther - various additions.
And many other people who sent bug reports, feature requests. If you
feel that I forgot your name in this list, then please send me an email
and I'll add you.
Last changed
============
09/02/2015

216
README.md Normal file
View File

@@ -0,0 +1,216 @@
# note - a perl script for maintaining notes.
> [!CAUTION]
> This software is now being maintained on [Codeberg](https://codeberg.org/scip/note/).
This is the perl script 'note' in version 1.4.2 from 24/09/2024.
## Introduction
This is a small console program written in perl, which allows you to
manage notes similar to programs like "knotes" from command line.
There are a couple of different databases backends, which you can use
with note:
* **binary** - this is the default backend
and uses a binary file to store your notes.
* **mysql** - this backend uses a mysql
database to store your notes. You can switch
easily to another DBMS since this module uses
the Perl standard module "DBI" for database-
access. See below for more info on this topic!
* **dbm** - this module uses two DBM files
for data storage and requires the module DB_FILE,
which is part of the perl standard distribution.
See below for more details about the DBM module.
* **general** - uses the module Config::General
for storage, which makes the data file portable,
since it is a plain ascii file (binary content
will be base64 encoded).
* **text** - uses the Storable module for data
storage (a serializer). Storable is included with
perl, and since it's written in C, it's very fast.
But the resulting data files are not that portable
as the once of NOTEDB::general are.
* **pwsafe3** - uses the
[PWSAFE3](https://github.com/pwsafe/pwsafe/blob/master/docs/formatV3.txt)
file format, which is securely encrypted. The file can be opened
with any other program which supports the format. There are windows
programs and apps for mobile phones available. **I highly recommend
to use this backend if you ever intend to store sensitive
information in it!**
## Where to
You can download the source at http://www.daemon.de/NOTE or
https://codeberg.org/scip/note.
If you are using debian, you run `can apt-get ìnstall note`.
If you are using gentoo, you can emerge it.
## Features
* Several different database backends, mysql(DBI), dbm,
binary (bin file), general and text (text files).
* Command line interface using the standard perl module
Getopt::Long, which allows you to use short or long
command-line options.
* Interactive interface (pure ascii), the following functions
are available in interactive mode: list, display, topic,
delete, edit, help.
* Highly configurable using a perlish configfile ~/.noterc.
although it is configurable it is not required, note can
run without a configfile using useful default presets.
* Colourized output is supported using ASCII Escape-Sequences.
* The user can customize the color for each item.
* Data can be stored in various different database backends,
since all database access is excluded from the program itself
in perl modules.
* Notes can be deleted, edited and you can search trough your notes.
* Notes can be categorized. Each category (topic) can contain multiple
notes and even more sup-topics. There is no limitation about
sub topics.
* You can view all notes in a list and it is possible only to view
notes under a certain topic.
* There is a tree-view, which allows you to get an overview of your
topic-hierarchy.
* Notes can be encrypted using DES or IDEA algorithms and Crypt::CBC.
* You can dump the contents of your note database into a plain text
file, which can later be imported. Imports can be appended or it can
overwrite an existing database (`-o`).
* Note has scripting capabilities, you can create a new note by piping
another commands output to note, you can also import a notedump from
stdin as well es duming to stdout instead a file. Additional, there
is an option `--raw` available, which prints everything out completely
without formatting.
* for better performance, note can cache the database for listings
or searching.
* It can be installed without root-privileges.
* If Term::ReadLine (and Term::ReadLine::Gnu) is installed, history
and auto-completion are supported in interactive mode.
* Last, a while ago a user stated: "... it simply does, what it
says ..."
## Requirements
You need the following things:
* perl installed (5.004x)
* The module IO::Seekable and Fcntl, which should be
already installed with your perl distribuion if
you want to use the binary database backend.
* DBI module and DBI::mysql if you want to use the
mysql database backend.
* The module DB_FILE if you want to use the DBM module.
* Getopt::Long (part of perl std distribution)
* Term::ReadLine and optionally Term::ReadLine::Gnu if
you want to use the auto-completion and history functionality.
* Config::General if you want to use the NOTEDB::general
backend.
* YAML is needed to create backups using -D. Please note,
that this format is deprecated starting with 1.4.0.
**The support will be removed in 1.5.0. Please switch to JSON
format as soon as possible, either by using the -j
commandline option or the UseJSON configuration value.**
* The Crypt::PWSafe3 module if you want to use the pwsafe3 backend.
## Installation
Unpack the tar-ball and issue the following command:
`$ perl Makefile.PL`
This creates the Makefile neccessary for installing.
You may add some additional variables to the command line, the
most important one is PREFIX.
Then enter the following command to prepare the installation
process:
`$ make`
After that, you are ready to install. Become root and issue:
`# make install`
The installation process installs all modules for every available
data backends. The default note configuration does not require
additional perl modules.
If you want to use the mysql backend refer to the installation
instructions for the mysql database installation in mysql/README.
If you want to use encryption support, you will need at least
Crypt:CBC and Crypt::Blowfish (or Crypt::DES or whatever you
prefer). You won't need to manually install any of this if you want to
use the pwsafe3 backend, in that case install Crypt::PWSafe3 with all
its dependencies.
## Configuration
This version of note doesn't necessarily need a configuration
file. But you can have one and change some default values. Take a look
at the file config/noterc provided with this tarball. There are
detailed instructions about every available parameter. Simply copy
this file into your home-directory and name it `.noterc` If you decide
not to use the default database backend (a binary file), you will
*need* a configuration!
## Usage
Refer to the note(1) manpage for usage instructions.
## Getting help
Although I'm happy to hear from note users in private email,
that's the best way for me to forget to do something.
In order to report a bug, unexpected behavior, feature requests or to
submit a patch, please open an issue on github:
https://codeberg.org/scip/note/issues.
## Deprecation notes
The **binary** database format will be removed with version 1.5.0. No
deprecation note is being printed for now.
The **text** database format will be either removed or will use
another backend module for security reasons. The perl module Storable
will not be used anymore.
## Copyright and License
Copyright (c) 1999-2013 Thomas Linden
Copyright (c) 2013-2024 Thomas von Dein
Licensed under the GNU GENERAL PUBLIC LICENSE version 3.
You can read the complete GPL at: http://www.gnu.org/copyleft/gpl.html
## Author
T.v.Dein <tom AT vondein DOT org>
## Contributors / Credits
Shouts to all those guys who helped me to enhance note: THANKS A LOT!
Jens Heunemann - sub tree.
Peter Palmreuther - various additions.
And many other people who sent bug reports, feature requests. If you
feel that I forgot your name in this list, then please send me an email
and I'll add you.

6
TODO
View File

@@ -1,6 +0,0 @@
- &output() has to be rewritten, its a historically
growed mutant.
- ncurses support

73
UPGRADE
View File

@@ -1,73 +0,0 @@
1.0.5 important note upgrade information
========================================
If you are upgrading from previous versions of note, you
will need to create a new config file, since the format of
that file has completely changed!
Take a look at the sample in config/noterc for details.
note will NOT work with an existing database and an old config.
You have to create a new config based on your old settings.
Please don't forget to make a backup of your database before
upgrading! I am not responsible for data loss!
I told ya...
Thomas Linden <tom@daemon.de>
READ THIS FILE, IF YOU ARE UPGRADING FROM 0.9 TO 1.0.x
======================================================
In any case: BACKUP your existing note database!!!!!!!
The format has not changed, but some default values
(see the new config file-sample). Use this command
to save your note database with your *old* version
of note:
"note -D"
This works with both the mysql and the binary version.
You need to reedit your configfile. Please refer to the
sample config in config/noterc.
======================================================
This version of note has now encryption support build in.
If you decide to use it, you need to re-initialize your
note database. That's why, because your current database
is unencrypted and *if* you want to secure your data, you
need to secure everything. That means, your existing data
must be encrypted before you can use this new capability!
Follow this steps:
o backup existing db:
$ note -D
o backup the db:
$ cp .notedb .notedb.save
or (for mysql users!):
$ cp -r /usr/local/mysql/data/notedb ~/notedb.mysql.save
o go into note and delete all existing notes:
$ note -d 1-20 (or however)
o now upgrade your note installation:
$ perl Makefile.PL; make install
o re-configure note. Turn $USE_CRYPT on by setting it
to "YES".
o re-initialize your database:
$ note -I note.dump.2323 (or whatever)
note will prompt you for a passphrase. It will be used
by Crypt::CBC for encrypting your data.
From now on, your data is encrypted. You will need the passphrase
you set above for decrypting it! So - don't forget it!
======================================================
AGAIN: YOU HAVE BEEN WARNED! DO NOT UPGRADE WITHOUT MADE A
BACKUP OF YOUR DATABASE! I AM NOT RESPONSIBLE IF YOU
LOOSE DATA!

View File

@@ -1 +0,0 @@
1.3.26

1859
bin/note

File diff suppressed because it is too large Load Diff

View File

@@ -1,55 +0,0 @@
#!/bin/sh
# create notes with topics which then represents the corresponding
# directory structure. Depending on how many files the directory
# contains, the resulting note-database may become very large.
# It will then have thousands of notes!
STARTDIR=$1
case $STARTDIR in
"")
echo "usage: stresstest.sh <directory>"
exit 1
;;
*)
LOCPFAD=`echo $STARTDIR | grep "^[a-zA-Z0-9.]"`
case $LOCPFAD in
"")
#echo nix
;;
*)
STARTDIR=`echo $STARTDIR | sed 's/^\.*//'`
STARTDIR="`pwd`/$STARTDIR"
STARTDIR=`echo $STARTDIR | sed 's/\/\//\//g'`
;;
esac
;;
esac
stress ()
{
FILES=""
for file in `ls $1|sort`
do
echo "$1/$file"
if [ -d "$1/$file" ] ; then
stress "$1/$file"
else
#echo "$1/" > /tmp/$$
#echo $file >> /tmp/$$
#`cat /tmp/$$ | note -`
FILES="$FILES $file"
fi
done
echo "$1/" > /tmp/$$
echo "$FILES" >> /tmp/$$
case $FILES in
"")
;;
*)
RES=`cat /tmp/$$ | note -`
;;
esac
FILES=""
}
stress $STARTDIR

View File

@@ -1,292 +0,0 @@
# note 1.3.13 -*- sh -*-
#
# This is a sample config for the note script
# There are useful defaults set in note itself.
#
# Copy it to your $HOME as .noterc
#
# note is Copyright (c) 1999-2013 Thomas Linden.
# You can contact me per email: <tom at linden dot at>
#
# Comments start with #, empty lines will be ignored.
#
# To turn on an option, set it to: 1, on or yes
# To turn off an option, set it to: 0, off or no
#
# An option consists of an atribute-value pair separated
# by minimum one space (more spaces and/or tabs are allowed)
# and an optional equal sign in between.
#
# Variable names are case in-sensitive.
#
# Refer to the manpage to learn more about the config
#
# you need to decide which database backend you want
# to use. Please refer to the corresponding documentation
# for closer information about the certain backend!
# Currently supported types: "binary", "dbm", "mysql",
# "general", "dumper", "pwsafe3" or "text".
# You must also edit/uncomment one section below for the
# backend you want to use!
dbdriver = binary
#
# BINARY backend (the default)
binary::dbname = ~/.notedb # filename
binary::MaxNoteByte = 4096 # max bytes per note entry
binary::MaxTimeByte = 64 # max bytes for the date
#
# MYSQL backend
mysql::dbhost = localhost # hostname
mysql::dbport = 3306 # tcp port
mysql::dbuser = you # db login
mysql::dbpasswd = # db password
mysql::dbname = # database name (default: note)
mysql::encrypt_passwd = 0 # mysql::dbpasswd is
# encrypted (note --encrypt)
#
# DBM backend
dbm::directory = ~/.notedbm # directory
#
# GENERAL backend
general::dbname = ~/.notedb # filename
#
# TEXT backend
text::dbname = ~/.notedb # filename
#
# DUMPER backend
dumper::dbname = ~/.notedb # filename
#
# Password Safe v3 backend
# Some notes on this one:
# This backend maintains encryption itself, which is
# mandatory as well. So you'll have to disable encryption
# (UseEncryption = NO)!
#
# The Password Safe v3 file has its own fields for
# password and username, which note doesn't have. To be
# compatible, the pwsafe3 backend parses the note text
# for those fields and stores them accordignly to the db:
#
# For username field: user|username|login|account|benutzer
# For passwd field: password|pass|passwd|kennwort|pw
#
# If it doesn't find it, it will put empty strings
# into the pwsafe3 database.
#
# The pwsafe3 database can be accessed by Password Safe
# (see: http://passwordsafe.sourceforge.net/) or other
# tools which support the format (see:
# http://passwordsafe.sourceforge.net/relatedprojects.shtml)
pwsafe3::dbname = ~/db.psafe3 # filename
#
# You can use encryption with note, that means notes and
# timestamps will be stored encrypted. This is supported
# by every db-backend.
UseEncryption = NO
#
# Specify the encryption protocol. The appropriate perl
# module needs to be installed. Possible velues are
# IDEA, DES or Blowfish, the default is IDEA.
CryptMethod = IDEA
#
# You can run note always in interactive mode by simply
# typing "note". The default is: YES.
AlwaysInteractive = YES
#
# In interactive mode, note issues a list command if you
# simply hit enter. By turning this on, it will issue a
# longlist command instead if you hit just enter.
# The default is: NO
DefaultLong = NO
#
# You can use an external editor everytime from note instead
# of STDIN for creating new notes. The default is: YES
AlwaysEditor = YES
#
# By default, note looks in the environment for a variable
# $EDITOR or, if this is not the case, for $VISUAL and as
# fallback it uses 'vi'.
# You can override this by setting this variable here.
PreferredEditor =
#
# If you don't prefer that note updates the timestamp of a
# note after editing, turn this on. It will
# keep the original timestamp if this option is set.
# The default is: NO
KeepTimeStamp = NO
#
# You can specify your own topic separator here.
# The default topic separator is a normal slash: "/"
TopicSeparator = /
#
# The maximum width for displaying a note, in CHARS.
# Depends on your screen-size. You can set it to
# "auto", if you wish that note should determine the
# available size automatically.
MaxLen = auto
#
# Turn this off if you dont want note to automatically
# clear the screen after displaying something and after
# exit. The default is: NO
AutoClear = NO
#
# note can use colors for output, turn this of, if
# you don't like it, or if your terminal does
# not support it. The default is: YES
UseColors = NO
#
# Color-definitions of the various items. Will only
# take effect, if "UseColors" is turned on!
#
# The following colors are available:
# black, red, green, yellow, blue, magenta, cyan and white.
#
# For bold color write it uppercase (BLACK will be bold black).
# For underlined color append an underscore (blue_ will be underlined blue).
# For inverted color append an "I" (greenI will be inverted green).
BorderColor BLACK
NumberColor blue
NoteColor green
TimeColor black
TopicColor BLACK
#
# Additional to colors, you can also do a little bit of formatting your
# notes (bold, underlined, italic) text. The default is: YES.
FormatText = NO
#
# You might specify your own directory for temporary files.
# note needs to create some temp files during editing of notes.
# You could protect this directory using the command: chmod 700 directory.
# The default is: /tmp
TempDirectory = ~/tmp
#
# You can jump to a topic by typing "cd 13" in interactive mode.
# The deault is: NO
ShortCd = YES
#
# note can use a cached copy of the note database for list/tree/search
# this is currently only supported by the binary and the mysql backends,
# the general and text backends have an internal cache.
# The default is: NO
Cache = NO
#
# You can define your very own time format for time stamps
# YY - the last 2 digits of a year
# YYYY - year
# MM - month
# DD - day
# hh - hours
# mm - minutes
# ss - seconds
# This is the default: (18.10.2000 21:32:08)
TimeFormat = DD.MM.YYYY hh:mm:ss
#
# You can make note readonly which is useful for database copies
# The default is: NO
ReadOnly = NO
#
# Note may separate titles and topics using horizontal lines when
# listing them. You can turn on this behavior by setting
# PrintLines to YES.
# The default is: NO
PrintLines = NO
#
# Add a hash to identify notes. Such a hash will persist several
# importy/export cycles and makes each single note unique.
AddTicket = NO
#
# Show an entry on startup. If you want it, create such an entry
# and supply its number here
motd =
#
#
# That's all about it for now.
# If you still have any questiosn, please feel free to contact
# me by email: Thomas Linden <tom at linden dot at>
#
#

154
config/rc
View File

@@ -1,154 +0,0 @@
comments start with #, empty lines will be ignored.
1 turns an option on, 0 turns it off.
An option consists of an atribute-value pair separated
by minimum one space (more spaces and/or tabs are allowed)
Your home directory, better do not change it!
can be an environment variable or a path
Home $ENV{'HOME'}
specify the path, where the NOTEDB lib directory
resides. This will only used if it is not
installed inside the perl-lib directory structure!
LibPath /usr/local/lib
you need to decide which database backend you want
to use. Please refer to the corresponding documentation
for closer information about the certain backend!
Currently supported types: "binary", "dbm" or "mysql".
You must also edit/uncomment one section below for the
backend you want to use!
DbDriver binary
backend specific settings for sql backend
DbHost localhost
DbUser you
DbPasswd
DbName mynotes
DbTable note
FieldNumber number
FieldNote note
FieldDate date
use an encrypted password, generate it with note "--encrypt_passwd"
encrypt_passwd 1
#### specific end ###
backend specific settings for binary(default) backend
NoteDb ~/.notedb
Define the maximum bytes fields can have in a
note-entry. Do not change MaxTimeByte to less than 64!
MaxNoteByte 4096
MaxTimeByte 64
#### specific end ###
backend specific settings for DBM backend
this must be an existing directory!
#DbName /home/you/.notedbm
#### specific end ###
You can use encryption with note, that means notes and
timestamps will be stored encrypted. This is supported
by every db-backend.
Set to 1 to turn it on. The Default is 0 (off)
UseEncryption 0
Specify the encryption protocol. The appropriate perl
module needs to be installed. Possible velues are
IDEA, DES or Blowfish, the default is IDEA.
CryptMethod IDEA
You can run note always in interactive mode by simply
typing "note". Set this option to 1 to turn it on.
The default is 0 (off).
AlwaysInteractive 0
In interactive mode, note issues a list command if you
simply hit enter. By turning this on, it will issue a
longlist command instead if you hit just enter.
The default is 0 (off)
DefaultLong 0
You can use an external editor everytime from note instead
of STDIN for creating new notes. Set to 1 to turn it on.
The default is 0 (off).
AlwaysEditor 0
uncomment and edit it, if you want to use another
editor than the default $EDITOR or as fallback vi.
#PreferredEditor emacs
If you dont prefer that note updates the timestamp of a
note after editing, turn this on. It will
keep the original timestamp if this option is set.
The default is 0(off), to turn it on set to 1.
KeepTimeStamp 0
You can specify your own topic separator here.
the default topic separator is a normal slash: "/"
see README for details about topics!
TopicSeparator /
The maximum width for displaying a note, in CHARS.
Depends on your screen-size. You can set it to
"auto", if you wish that note sould determine the
available size, but it experimental, be aware!
MaxLen 30
note can use colors for output, set this option to
1, if you don't want it, or if your terminal does
not support it, set to 0. The default is 1 (on).
UseColors 1
Color-definitions of the various items. Will only
take effect, if "UseColors" is turned on!
BorderColor BLACK
NumberColor blue
NoteColor green
TimeColor black
TopicColor BLACK
The following colors are available:
black, red, green, yellow, blue, magenta, cyan and white.
for bold color write it uppercase (BLACK will be bold black)
for underlined color append an underscore (blue_ will be underlined blue)
for inverted color append an "I" (greenI will be inverted green)
Additional to colors, you can also do a little bit of formatting your
notes (bold, underlined, italic), see README!
You need to set this Option to 1, if you decide to make use of this
capabily
FormatText 1
You might specify your own directory for temporary files.
note needs to create some temp files during editing of notes.
You could protect this directory using the command: chmod 700 directory.
The default is /tmp
TempDirectory /home/you/tmp
You can jump to a topic by typing "cd 13" in interactive mode.
You need to set thi soption to 1 if you want to use this feature.
ShortCd 0
That's all about it for now.
If you still have any questiosn, please feel free to contact
me by email: Thomas Linden <tom@daemon.de>

View File

@@ -1,306 +0,0 @@
#
# this is a generic module, used by note database
# backend modules.
#
# Copyright (c) 2000-2017 T.v.Dein <tlinden@cpan.org>
package NOTEDB;
use Exporter ();
use vars qw(@ISA @EXPORT $crypt_supported);
$NOTEDB::VERSION = "1.45";
BEGIN {
# make sure, it works, otherwise encryption
# is not supported on this system!
eval { require Crypt::CBC; };
if($@) {
$NOTEDB::crypt_supported = 0;
}
else {
$NOTEDB::crypt_supported = 1;
}
}
sub no_crypt {
$NOTEDB::crypt_supported = 0;
}
sub use_crypt {
my($this,$key,$method) = @_;
my($cipher);
if($NOTEDB::crypt_supported == 1) {
eval {
$cipher = new Crypt::CBC($key, $method);
};
if($@) {
print "warning: Crypt::$method not supported by system!\n";
$NOTEDB::crypt_supported = 0;
}
else {
$this->{cipher} = $cipher;
}
}
else{
print "warning: Crypt::CBC not supported by system!\n";
}
}
sub use_cache {
#
# this sub turns on cache support
#
my $this = shift;
$this->{use_cache} = 1;
$this->{changed} = 1;
}
sub cache {
#
# store the whole db as hash
# if use_cache is turned on
#
my $this = shift;
if ($this->{use_cache}) {
my %res = @_;
%{$this->{cache}} = %res;
}
}
sub unchanged {
#
# return true if $this->{changed} is true, this will
# be set to true by writing subs using $this->changed().
#
my $this = shift;
return 0 if(!$this->{use_cache});
if ($this->{changed}) {
$this->{changed} = 0;
return 0;
}
else {
print "%\n";
return 1;
}
}
sub changed {
#
# turn on $this->{changed}
# this will be used by update or create subs.
#
my $this = shift;
$this->{changed} = 1;
return 1;
}
sub generate_search {
#
# get user input and create perlcode ready for eval
# sample input:
# "ann.a OR eg???on AND u*do$"
# resulting output:
# "$match = 1 if(/ann\.a/i or /eg...on/i and /u.*do\$/i );
#
my($this, $string) = @_;
my $case = "i";
if ($string =~ /^\/.+?\/$/) {
return $string;
}
elsif (!$string) {
return "/^/";
}
# we will get a / in front of the first word too!
$string = " " . $string . " ";
# check for apostrophs
$string =~ s/(?<=\s)(\(??)("[^"]+"|\S+)(\)??)(?=\s)/$1 . $this->check_exact($2) . $3/ge;
# remove odd spaces infront of and after <20>and<6E> and <20>or<6F>
$string =~ s/\s\s*(AND|OR)\s\s*/ $1 /g;
# remove odd spaces infront of <20>(<28> and after <20>)<29>
$string =~ s/(\s*\()/\(/g;
$string =~ s/(\)\s*)/\)/g;
# remove first and last space so it will not masked!
$string =~ s/^\s//;
$string =~ s/\s$//;
# mask spaces if not infront of or after <20>and<6E> and <20>or<6F>
$string =~ s/(?<!AND)(?<!OR)(\s+?)(?!AND|OR)/'\s' x length($1)/ge;
# add first space again
$string = " " . $string;
# lowercase AND and OR
$string =~ s/(\s??OR\s??|\s??AND\s??)/\L$1\E/g;
# surround brackets with at least one space
$string =~ s/(?<!\\)(\)|\()/ $1 /g;
# surround strings with slashes
$string =~ s/(?<=\s)(\S+)/ $this->check_or($1, $case) /ge;
# remove slashes on <20>and<6E> and <20>or<6F>
$string =~ s/\/(and|or)\/$case/$1/g;
# remove spaces inside /string/ constructs
$string =~ s/(?<!and)(?<!or)\s*\//\//g;
$string =~ s/\/\s*(?!and|or)/\//g;
#my $res = qq(\$match = 1 if($string););
return qq(\$match = 1 if($string););
#print $res . "\n";
#return $res;
}
sub check_or {
#
# surrounds string with slashes if it is not
# <20>and<6E> or <20>or<6F>
#
my($this, $str, $case) = @_;
if ($str =~ /^\s*(or|and)\s*$/) {
return " $str ";
}
elsif ($str =~ /(?<!\\)[)(]/) {
return $str;
}
else {
return " \/$str\/$case ";
}
}
sub check_exact {
#
# helper for generate_search()
# masks special chars if string
# not inside ""
#
my($this, $str) = @_;
my %wildcards = (
'*' => '.*',
'?' => '.',
'[' => '[',
']' => ']',
'+' => '\+',
'.' => '\.',
'$' => '\$',
'@' => '\@',
'/' => '\/',
'|' => '\|',
'}' => '\}',
'{' => '\{',
);
my %escapes = (
'*' => '\*',
'?' => '\?',
'[' => '[',
']' => ']',
'+' => '\+',
'.' => '\.',
'$' => '\$',
'@' => '\@',
'(' => '\(',
')' => '\)',
'/' => '\/',
'|' => '\|',
'}' => '\}',
'{' => '\{',
);
# mask backslash
$str =~ s/\\/\\\\/g;
if ($str =~ /^"/ && $str =~ /"$/) {
# mask bracket-constructs
$str =~ s/(.)/$escapes{$1} || "$1"/ge;
}
else {
$str =~ s/(.)/$wildcards{$1} || "$1"/ge;
}
$str =~ s/^"//;
$str =~ s/"$//;
# mask spaces
$str =~ s/\s/\\s/g;
return $str;
}
sub lock {
my ($this) = @_;
if (-e $this->{LOCKFILE}) {
open LOCK, "<$this->{LOCKFILE}" or die "could not open $this->{LOCKFILE}: $!\n";
my $data = <LOCK>;
close LOCK;
chomp $data;
print "-- waiting for lock by $data --\n";
print "-- remove the lockfile if you are sure: \"$this->{LOCKFILE}\" --\n";
}
my $timeout = 60;
eval {
local $SIG{ALRM} = sub { die "timeout" };
local $SIG{INT} = sub { die "interrupted" };
alarm $timeout - 2;
while (1) {
if (! -e $this->{LOCKFILE}) {
umask 022;
open LOCK, ">$this->{LOCKFILE}" or die "could not open $this->{LOCKFILE}: $!\n";
flock LOCK, LOCK_EX;
my $now = scalar localtime();
print LOCK "$ENV{USER} since $now (PID: $$)\n";
flock LOCK, LOCK_UN;
close LOCK;
alarm 0;
return 0;
}
printf " %0d\r", $timeout;
$timeout--;
sleep 1;
}
};
if($@) {
if ($@ =~ /^inter/) {
print " interrupted\n";
}
else {
print $@;
print " timeout\n";
}
return 1;
}
return 0;
}
sub unlock {
my ($this) = @_;
unlink $this->{LOCKFILE};
}
1;

View File

@@ -1,7 +0,0 @@
perl modules for note used as database backends.
the install.sh script will install both of them,
although you may only need one backend. Perhaps
other users on your system have oter ideas in mind...
Therefore, please ignore these file. There is nothing
to edit or to do. Simply leave this directory :-)

View File

@@ -1,496 +0,0 @@
#!/usr/bin/perl
# $Id: binary.pm,v 1.3 2000/08/11 00:05:58 zarahg Exp $
# Perl module for note
# binary database backend. see docu: perldoc NOTEDB::binary
#
package NOTEDB::binary;
$NOTEDB::binary::VERSION = "1.12";
use strict;
use IO::Seekable;
use File::Spec;
use FileHandle;
use Fcntl qw(LOCK_EX LOCK_UN);
use NOTEDB;
use Exporter ();
use vars qw(@ISA @EXPORT);
@ISA = qw(NOTEDB Exporter);
sub new {
my($this, %param) = @_;
my $class = ref($this) || $this;
my $self = {};
bless($self,$class);
$self->{NOTEDB} = $self->{dbname} = $param{dbname} || File::Spec->catfile($ENV{HOME}, ".notedb");
my $MAX_NOTE = $param{MaxNoteByte} || 4096;
my $MAX_TIME = $param{MaxTimeByte} || 64;
if(! -e $self->{NOTEDB}) {
open(TT,">$self->{NOTEDB}") or die "Could not create $self->{NOTEDB}: $!\n";
close (TT);
}
elsif(! -w $self->{NOTEDB}) {
print "$self->{NOTEDB} is not writable!\n";
exit(1);
}
my $TYPEDEF = "i a$MAX_NOTE a$MAX_TIME";
my $SIZEOF = length pack($TYPEDEF, () );
$self->{sizeof} = $SIZEOF;
$self->{typedef} = $TYPEDEF;
$self->{maxnote} = $MAX_NOTE;
$self->{LOCKFILE} = $self->{NOTEDB} . "~LOCK";
return $self;
}
sub DESTROY
{
# clean the desk!
}
sub version {
my $this = shift;
return $NOTEDB::binary::VERSION;
}
sub set_del_all
{
my $this = shift;
unlink $this->{NOTEDB};
open(TT,">$this->{NOTEDB}") or die "Could not create $this->{NOTEDB}: $!\n";
close (TT);
}
sub get_single {
my($this, $num) = @_;
my($address, $note, $date, $n, $t, $buffer, );
open NOTE, "+<$this->{NOTEDB}" or die "could not open $this->{NOTEDB}\n";
flock NOTE, LOCK_EX;
$address = ($num-1) * $this->{sizeof};
seek(NOTE, $address, IO::Seekable::SEEK_SET);
read(NOTE, $buffer, $this->{sizeof});
($num, $n, $t) = unpack($this->{typedef}, $buffer);
$note = $this->ude($n);
$date = $this->ude($t);
flock NOTE, LOCK_UN;
close NOTE;
return $note, $date;
}
sub get_all
{
my $this = shift;
my($num, $note, $date, %res);
if ($this->unchanged) {
return %{$this->{cache}};
}
open NOTE, "+<$this->{NOTEDB}" or die "could not open $this->{NOTEDB}\n";
flock NOTE, LOCK_EX;
my($buffer, $t, $n);
seek(NOTE, 0, 0); # START FROM BEGINNING
while(read(NOTE, $buffer, $this->{sizeof})) {
($num, $note, $date) = unpack($this->{typedef}, $buffer);
$t = $this->ude($date);
$n = $this->ude($note);
$res{$num}->{'note'} = $n;
$res{$num}->{'date'} = $t;
}
flock NOTE, LOCK_UN;
close NOTE;
$this->cache(%res);
return %res;
}
sub import_data {
my ($this, $data) = @_;
foreach my $num (sort keys %{$data}) {
my $pos = $this->get_nextnum();
$this->set_edit($pos, $data->{$num}->{note}, $data->{$num}->{date});
}
}
sub get_nextnum
{
my $this = shift;
my($num, $te, $me, $buffer);
if ($this->unchanged) {
$num = 1;
foreach (keys %{$this->{cache}}) {
$num++;
}
return $num;
}
open NOTE, "+<$this->{NOTEDB}" or die "could not open $this->{NOTEDB}\n";
flock NOTE, LOCK_EX;
seek(NOTE, 0, 0); # START FROM BEGINNING
while(read(NOTE, $buffer, $this->{sizeof})) {
($num, $te, $me) = unpack($this->{typedef}, $buffer);
}
$num += 1;
flock NOTE, LOCK_UN;
close NOTE;
return $num;
}
sub get_search
{
my($this, $searchstring) = @_;
my($buffer, $num, $note, $date, %res, $t, $n, $match);
my $regex = $this->generate_search($searchstring);
eval $regex;
if ($@) {
print "invalid expression: \"$searchstring\"!\n";
return;
}
$match = 0;
if ($this->unchanged) {
foreach my $num (keys %{$this->{cache}}) {
$_ = $this->{cache}{$num}->{note};
eval $regex;
if ($match) {
$res{$num}->{note} = $this->{cache}{$num}->{note};
$res{$num}->{date} = $this->{cache}{$num}->{date}
}
$match = 0;
}
return %res;
}
open NOTE, "+<$this->{NOTEDB}" or die "could not open $this->{NOTEDB}\n";
flock NOTE, LOCK_EX;
seek(NOTE, 0, 0); # START FROM BEGINNING
while(read(NOTE, $buffer, $this->{sizeof})) {
($num, $note, $date) = unpack($this->{typedef}, $buffer);
$n = $this->ude($note);
$t = $this->ude($date);
$_ = $n;
eval $regex;
if($match)
{
$res{$num}->{'note'} = $n;
$res{$num}->{'date'} = $t;
}
$match = 0;
}
flock NOTE, LOCK_UN;
close NOTE;
return %res;
}
sub set_edit {
my($this, $num, $note, $date) = @_;
$this->warn_if_too_big($note, $num);
my $address = ($num -1 ) * $this->{sizeof};
open NOTE, "+<$this->{NOTEDB}" or die "could not open $this->{NOTEDB}\n";
flock NOTE, LOCK_EX;
seek(NOTE, $address, IO::Seekable::SEEK_SET);
my $n = $this->uen($note);
my $t = $this->uen($date);
my $buffer = pack($this->{typedef}, $num, $n, $t);
print NOTE $buffer;
flock NOTE, LOCK_UN;
close NOTE;
$this->changed;
}
sub set_new {
my($this, $num, $note, $date) = @_;
$this->warn_if_too_big($note, $num);
open NOTE, "+<$this->{NOTEDB}" or die "could not open $this->{NOTEDB}\n";
flock NOTE, LOCK_EX;
seek(NOTE, 0, IO::Seekable::SEEK_END); # APPEND
my $n = $this->uen($note);
my $t = $this->uen($date);
my $buffer = pack($this->{typedef}, $num, $n, $t);
print NOTE $buffer;
flock NOTE, LOCK_UN;
close NOTE;
$this->changed;
}
sub set_del
{
my($this, $num) = @_;
my(%orig, $note, $date, $T, $setnum, $buffer, $n, $N, $t);
$setnum = 1;
%orig = $this->get_all();
return "ERROR" if (! exists $orig{$num});
delete $orig{$num};
# overwrite, but keep number!
open NOTE, ">$this->{NOTEDB}" or die "could not open $this->{NOTEDB}\n";
flock NOTE, LOCK_EX;
seek(NOTE, 0, 0); # START FROM BEGINNING
foreach $N (keys %orig) {
$n = $this->uen($orig{$N}->{'note'});
$t = $this->uen($orig{$N}->{'date'});
$buffer = pack( $this->{typedef}, $N, $n, $t);
# keep orig number, note have to call recount!
print NOTE $buffer;
seek(NOTE, 0, IO::Seekable::SEEK_END);
$setnum++;
}
flock NOTE, LOCK_UN;
close NOTE;
$this->changed;
return;
}
sub set_recountnums
{
my($this) = @_;
my(%orig, $note, $date, $T, $setnum, $buffer, $n, $N, $t);
$setnum = 1;
%orig = $this->get_all();
open NOTE, ">$this->{NOTEDB}" or die "could not open $this->{NOTEDB}\n";
flock NOTE, LOCK_EX;
seek(NOTE, 0, 0); # START FROM BEGINNING
foreach $N (sort {$a <=> $b} keys %orig) {
$n = $this->uen($orig{$N}->{'note'});
$t = $this->uen($orig{$N}->{'date'});
$buffer = pack( $this->{typedef}, $setnum, $n, $t);
print NOTE $buffer;
seek(NOTE, 0, IO::Seekable::SEEK_END);
$setnum++;
}
flock NOTE, LOCK_UN;
close NOTE;
$this->changed;
return;
}
sub uen
{
my $this = shift;
my($T);
if($NOTEDB::crypt_supported == 1) {
eval {
$T = pack("u", $this->{cipher}->encrypt($_[0]));
};
}
else {
$T = pack("u", $_[0]);
}
chomp $T;
return $T;
}
sub ude
{
my $this = shift;
my($T);
if($NOTEDB::crypt_supported == 1) {
eval {
$T = $this->{cipher}->decrypt(unpack("u",$_[0]));
};
}
else {
$T = unpack("u", $_[0]);
}
return $T;
}
sub warn_if_too_big {
my ($this, $note, $num) = @_;
my $len = length($this->uen($note));
if ($len > $this->{maxnote}) {
# calculate the 30% uuencoding overhead
my $overhead = int(($this->{maxnote} / 100) * 28);
# fetch what's left by driver
my $left = substr $note, $this->{maxnote} - $overhead;
$left = "\n$left\n";
$left =~ s/\n/\n> /gs;
print STDERR "*** WARNING $this->{version} WARNING ***\n"
."The driver encountered a string length problem with your\n"
."note entry number $num. The entry is too long. Either shorten\n"
."the entry or resize the database field for entries.\n\n"
."The following data has been cut off the entry:\n"
."\n$left\n\n";
my $copy = File::Spec->catfile($ENV{'HOME'}, "entry-$num.txt");
open N, ">$copy" or die "Could not open $copy: $!\n";
print N $note;
close N;
print "*** Wrote the complete note entry number $num to file: $copy ***\n";
}
}
sub _retrieve {
my ($this) = @_;
my $file = $this->{dbname};
if (-s $file) {
if ($this->changed() || $this->{unread}) {
open NOTE, "+<$this->{NOTEDB}" or die "could not open $this->{NOTEDB}\n";
flock NOTE, LOCK_EX;
my($buffer, $t, $n, %res);
seek(NOTE, 0, 0); # START FROM BEGINNING
while(read(NOTE, $buffer, $this->{sizeof})) {
my ($num, $note, $date) = unpack($this->{typedef}, $buffer);
$t = $this->ude($date);
$n = $this->ude($note);
$res{$num}->{'note'} = $n;
$res{$num}->{'date'} = $t;
}
flock NOTE, LOCK_UN;
close NOTE;
$this->cache(%res);
return %res;
}
else {
return %{$this->{data}};
}
}
else {
return ();
}
}
sub _store {
# compatibility dummy
return 1;
}
1; # keep this!
__END__
=head1 NAME
NOTEDB::binary - module lib for accessing a notedb from perl
=head1 SYNOPSIS
# include the module
use NOTEDB;
# create a new NOTEDB object
$db = new NOTEDB("binary", "/home/tom/.notedb", 4096, 24);
# decide to use encryption
# $key is the cipher to use for encryption
# $method must be either Crypt::IDEA or Crypt::DES
# you need Crypt::CBC, Crypt::IDEA and Crypt::DES to have installed.
$db->use_crypt($key,$method);
# do not use encryption
# this is the default
$db->no_crypt;
# get a single note
($note, $date) = $db->get_single(1);
# search for a certain note
%matching_notes = $db->get_search("somewhat");
# format of returned hash:
#$matching_notes{$numberofnote}->{'note' => 'something', 'date' => '23.12.2000 10:33:02'}
# get all existing notes
%all_notes = $db->get_all();
# format of returnes hash like the one from get_search above
# get the next noteid available
$next_num = $db->get_nextnum();
# modify a certain note
$db->set_edit(1, "any text", "23.12.2000 10:33:02");
# create a new note
$db->set_new(5, "any new text", "23.12.2000 10:33:02");
# delete a certain note
$db->set_del(5);
# turn on encryption. CryptMethod must be IDEA, DES or BLOWFISH
$db->use_crypt("passphrase", "CryptMethod");
# turn off encryption. This is the default.
$db->no_crypt();
=head1 DESCRIPTION
You can use this module for accessing a note database. There are currently
two versions of this module, one version for a SQL database and one for a
binary file (note's own database-format).
However, both versions provides identical interfaces, which means, you do
not need to change your code, if you want to switch to another database format.
Currently, NOTEDB module is only used by note itself. But feel free to use it
within your own project! Perhaps someone want to implement a webinterface to
note...
=head1 USAGE
please see the section SYNOPSIS, it says it all.
=head1 AUTHOR
Thomas Linden <tom@daemon.de>.
=cut

View File

@@ -1,269 +0,0 @@
#!/usr/bin/perl
# $Id: dbm.pm,v 1.3 2000/08/11 00:05:58 zarahg Exp $
# Perl module for note
# DBM database backend. see docu: perldoc NOTEDB::dbm
#
package NOTEDB::dbm;
$NOTEDB::dbm::VERSION = "1.41";
use DB_File;
use NOTEDB;
use strict;
use Exporter ();
use vars qw(@ISA @EXPORT %note %date);
@ISA = qw(NOTEDB Exporter);
sub new
{
my($this, %param) = @_;
my $class = ref($this) || $this;
my $self = {};
bless($self,$class);
my $notefile = "note.dbm";
my $timefile = "date.dbm";
my $dbm_dir = $self->{dbname} = $param{dbname} || File::Spec->catfile($ENV{HOME}, ".note_dbm");
if (! -d $dbm_dir) {
# try to make it
mkdir $dbm_dir || die "Could not create $dbm_dir: $!\n";
}
tie %note, "DB_File", "$dbm_dir/$notefile" || die "Could not tie $dbm_dir/$notefile: $!\n";
tie %date, "DB_File", "$dbm_dir/$timefile" || die "Could not tie $dbm_dir/$timefile: $!\n";
$self->{LOCKFILE} = $param{dbname} . "~LOCK";
return $self;
}
sub DESTROY
{
# clean the desk!
untie %note, %date;
}
sub version {
my $this = shift;
return $this->{version};
}
sub get_single
{
my($this, $num) = @_;
my($note, $date);
return $this->ude ($note{$num}), $this->ude($date{$num});
}
sub get_all
{
my $this = shift;
my($num, $note, $date, %res, $real);
foreach $num (sort {$a <=> $b} keys %date) {
$res{$num}->{'note'} = $this->ude($note{$num});
$res{$num}->{'date'} = $this->ude($date{$num});
}
return %res;
}
sub import_data {
my ($this, $data) = @_;
foreach my $num (keys %{$data}) {
my $pos = $this->get_nextnum();
$note{$pos} = $this->ude($note{$num}->{note});
$date{$pos} = $this->ude($date{$num}->{date});
}
}
sub get_nextnum
{
my($this, $num);
foreach (sort {$a <=> $b} keys %date) {
$num = $_;
}
$num++;
return $num;
}
sub get_search
{
my($this, $searchstring) = @_;
my($num, $note, $date, %res, $match);
my $regex = $this->generate_search($searchstring);
eval $regex;
if ($@) {
print "invalid expression: \"$searchstring\"!\n";
return;
}
$match = 0;
foreach $num (sort {$a <=> $b} keys %date) {
$_ = $this->ude($note{$num});
eval $regex;
if ($match) {
$res{$num}->{'note'} = $this->ude($note{$num});
$res{$num}->{'date'} = $this->ude($date{$num});
}
$match = 0;
}
return %res;
}
sub set_recountnums
{
my $this = shift;
my(%Note, %Date, $num, $setnum);
$setnum = 1;
foreach $num (sort {$a <=> $b} keys %note) {
$Note{$setnum} = $note{$num};
$Date{$setnum} = $date{$num};
$setnum++;
}
%note = %Note;
%date = %Date;
}
sub set_edit
{
my($this, $num, $note, $date) = @_;
$note{$num} = $this->uen($note);
$date{$num} = $this->uen($date);
}
sub set_new
{
my($this, $num, $note, $date) = @_;
$this->set_edit($num, $note, $date); # just the same thing
}
sub set_del
{
my($this, $num) = @_;
my($note, $date, $T);
($note, $date) = $this->get_single($num);
return "ERROR" if ($date !~ /^\d/);
delete $note{$num};
delete $date{$num};
}
sub set_del_all
{
my($this) = @_;
%note = ();
%date = ();
return;
}
sub uen
{
my $this = shift;
my($T);
if($NOTEDB::crypt_supported == 1) {
eval {
$T = pack("u", $this->{cipher}->encrypt($_[0]));
};
}
else {
$T = $_[0];
}
chomp $T;
return $T;
}
sub ude
{
my $this = shift;
my($T);
if($NOTEDB::crypt_supported == 1) {
eval {
$T = $this->{cipher}->decrypt(unpack("u",$_[0]))
};
return $T;
}
else {
return $_[0];
}
}
1; # keep this!
__END__
=head1 NAME
NOTEDB::dbm - module lib for accessing a notedb from perl
=head1 SYNOPSIS
# include the module
use NOTEDB;
# create a new NOTEDB object (the last 4 params are db table/field names)
$db = new NOTEDB("mysql","note","/home/user/.notedb/");
# get a single note
($note, $date) = $db->get_single(1);
# search for a certain note
%matching_notes = $db->get_search("somewhat");
# format of returned hash:
#$matching_notes{$numberofnote}->{'note' => 'something', 'date' => '23.12.2000 10:33:02'}
# get all existing notes
%all_notes = $db->get_all();
# format of returnes hash like the one from get_search above
# get the next noteid available
$next_num = $db->get_nextnum();
# recount all noteids starting by 1 (usefull after deleting one!)
$db->set_recountnums();
# modify a certain note
$db->set_edit(1, "any text", "23.12.2000 10:33:02");
# create a new note
$db->set_new(5, "any new text", "23.12.2000 10:33:02");
# delete a certain note
$db->set_del(5);
=head1 DESCRIPTION
You can use this module for accessing a note database. This is the dbm module.
It uses the DB_FILE module to store it's data and it uses DBM files for tis purpose.
Currently, NOTEDB module is only used by note itself. But feel free to use it
within your own project! Perhaps someone want to implement a webinterface to
note...
=head1 USAGE
please see the section SYNOPSIS, it says it all.
=head1 AUTHOR
Thomas Linden <tom@daemon.de>.
=cut

View File

@@ -1,371 +0,0 @@
# Perl module for note
# text database backend. see docu: perldoc NOTEDB::text
# using Storable as backend.
package NOTEDB::dumper;
$NOTEDB::dumper::VERSION = "1.02";
use strict;
use Data::Dumper;
use File::Spec;
use MIME::Base64;
use NOTEDB;
use Fcntl qw(LOCK_EX LOCK_UN);
use Exporter ();
use vars qw(@ISA @EXPORT);
@ISA = qw(NOTEDB Exporter);
sub new {
my($this, %param) = @_;
my $class = ref($this) || $this;
my $self = {};
bless($self,$class);
$self->{NOTEDB} = $self->{dbname} = $param{dbname} || File::Spec->catfile($ENV{HOME}, ".notedb");
if(! -e $param{dbname}) {
open(TT,">$param{dbname}") or die "Could not create $param{dbname}: $!\n";
close (TT);
}
elsif(! -w $param{dbname}) {
print "$param{dbname} is not writable!\n";
exit(1);
}
$self->{LOCKFILE} = $param{dbname} . "~LOCK";
$self->{mtime} = $self->get_stat();
$self->{unread} = 1;
$self->{data} = {};
return $self;
}
sub DESTROY
{
# clean the desk!
}
sub version {
my $this = shift;
return $NOTEDB::text::VERSION;
}
sub get_stat {
my ($this) = @_;
my $mtime = (stat($this->{dbname}))[9];
return $mtime;
}
sub set_del_all {
my $this = shift;
unlink $this->{NOTEDB};
open(TT,">$this->{NOTEDB}") or die "Could not create $this->{NOTEDB}: $!\n";
close (TT);
}
sub get_single {
my($this, $num) = @_;
my($address, $note, $date, $n, $t, $buffer, );
my %data = $this->get_all();
return ($data{$num}->{note}, $data{$num}->{date});
}
sub get_all {
my $this = shift;
my($num, $note, $date, %res);
if ($this->unchanged) {
return %{$this->{cache}};
}
my %data = $this->_retrieve();
foreach my $num (keys %data) {
$res{$num}->{note} = $this->ude($data{$num}->{note});
$res{$num}->{date} = $this->ude($data{$num}->{date});
}
$this->cache(%res);
return %res;
}
sub import_data {
my ($this, $data) = @_;
my %res = $this->_retrieve();
my $pos = (scalar keys %res) + 1;
foreach my $num (keys %{$data}) {
$res{$pos}->{note} = $this->uen($data->{$num}->{note});
$res{$pos}->{date} = $this->uen($data->{$num}->{date});
$pos++;
}
$this->_store(\%res);
}
sub get_nextnum {
my $this = shift;
my($num, $te, $me, $buffer);
if ($this->unchanged) {
$num = 1;
foreach (keys %{$this->{cache}}) {
$num++;
}
return $num;
}
my %data = $this->get_all();
my $size = scalar keys %data;
$num = $size + 1;
return $num;
}
sub get_search {
my($this, $searchstring) = @_;
my($buffer, $num, $note, $date, %res, $t, $n, $match);
my $regex = $this->generate_search($searchstring);
eval $regex;
if ($@) {
print "invalid expression: \"$searchstring\"!\n";
return;
}
$match = 0;
if ($this->unchanged) {
foreach my $num (keys %{$this->{cache}}) {
$_ = $this->{cache}{$num}->{note};
eval $regex;
if ($match) {
$res{$num}->{note} = $this->{cache}{$num}->{note};
$res{$num}->{date} = $this->{cache}{$num}->{date}
}
$match = 0;
}
return %res;
}
my %data = $this->get_all();
foreach my $num(sort keys %data) {
$_ = $data{$num}->{note};
eval $regex;
if($match)
{
$res{$num}->{note} = $data{$num}->{note};
$res{$num}->{date} = $data{$num}->{data};
}
$match = 0;
}
return %res;
}
sub set_edit {
my($this, $num, $note, $date) = @_;
my %data = $this->_retrieve();
$data{$num} = {
note => $this->uen($note),
date => $this->uen($date)
};
$this->_store(\%data);
$this->changed;
}
sub set_new {
my($this, $num, $note, $date) = @_;
$this->set_edit($num, $note, $date);
}
sub set_del {
my($this, $num) = @_;
my(%data, $note, $date, $T, $setnum, $buffer, $n, $N, $t);
$setnum = 1;
%data = $this->_retrieve();
return "ERROR" if (! exists $data{$num});
delete $data{$num};
$this->_store(\%data);
$this->changed;
return;
}
sub set_recountnums {
my($this) = @_;
my(%orig, %data, $note, $date, $T, $setnum, $buffer, $n, $N, $t);
$setnum = 1;
%orig = $this->_retrieve();
foreach $N (sort {$a <=> $b} keys %orig) {
$data{$setnum} = {
note => $orig{$N}->{note},
date => $orig{$N}->{date}
};
$setnum++;
}
$this->_store(\%data);
$this->changed;
return;
}
sub uen {
my ($this, $raw) = @_;
my($crypted);
if($NOTEDB::crypt_supported == 1) {
eval {
$crypted = $this->{cipher}->encrypt($raw);
return encode_base64($crypted);
};
}
else {
return $raw;
}
}
sub ude {
my ($this, $crypted) = @_;
my($raw);
if($NOTEDB::crypt_supported == 1) {
eval {
$raw = $this->{cipher}->decrypt(decode_base64($crypted));
};
return $raw;
}
else {
return $crypted;
}
}
sub _store {
my ($this, $data) = @_;
open N, ">$this->{NOTEDB}" or die "Could not open db: $!\n";
print N Data::Dumper->Dump([$data], [qw(*data)]);
close N;
}
sub _retrieve {
my $this = shift;
if (-s $this->{NOTEDB}) {
if ($this->changed() || $this->{unread}) {
open N, "<$this->{NOTEDB}" or die "Could not open db: $!\n";
my $content = join "", <N>;
close N;
my %data;
eval $content; # creates %data
$this->{unread} = 0;
$this->{data} = \%data;
return %data;
}
}
else {
return ();
}
}
1; # keep this!
__END__
=head1 NAME
NOTEDB::text - module lib for accessing a notedb from perl
=head1 SYNOPSIS
# include the module
use NOTEDB;
# create a new NOTEDB object
$db = new NOTEDB("text", "/home/tom/.notedb", 4096, 24);
# decide to use encryption
# $key is the cipher to use for encryption
# $method must be either Crypt::IDEA or Crypt::DES
# you need Crypt::CBC, Crypt::IDEA and Crypt::DES to have installed.
$db->use_crypt($key,$method);
# do not use encryption
# this is the default
$db->no_crypt;
# get a single note
($note, $date) = $db->get_single(1);
# search for a certain note
%matching_notes = $db->get_search("somewhat");
# format of returned hash:
#$matching_notes{$numberofnote}->{'note' => 'something', 'date' => '23.12.2000 10:33:02'}
# get all existing notes
%all_notes = $db->get_all();
# format of returnes hash like the one from get_search above
# get the next noteid available
$next_num = $db->get_nextnum();
# modify a certain note
$db->set_edit(1, "any text", "23.12.2000 10:33:02");
# create a new note
$db->set_new(5, "any new text", "23.12.2000 10:33:02");
# delete a certain note
$db->set_del(5);
# turn on encryption. CryptMethod must be IDEA, DES or BLOWFISH
$db->use_crypt("passphrase", "CryptMethod");
# turn off encryption. This is the default.
$db->no_crypt();
=head1 DESCRIPTION
You can use this module for accessing a note database. This backend uses
a text file for storage and Storable for accessing the file.
Currently, NOTEDB module is only used by note itself. But feel free to use it
within your own project! Perhaps someone want to implement a webinterface to
note...
=head1 USAGE
please see the section SYNOPSIS, it says it all.
=head1 AUTHOR
Thomas Linden <tom@daemon.de>.
=cut

View File

@@ -1,412 +0,0 @@
# Perl module for note
# general database backend. see docu: perldoc NOTEDB::general
# using Config::General as backend.
package NOTEDB::general;
$NOTEDB::general::VERSION = "1.04";
use strict;
#use Data::Dumper;
use File::Spec;
use Config::General qw(ParseConfig SaveConfig SaveConfigString);
use MIME::Base64;
use FileHandle;
use NOTEDB;
use Fcntl qw(LOCK_EX LOCK_UN);
use Exporter ();
use vars qw(@ISA @EXPORT);
@ISA = qw(NOTEDB Exporter);
sub new {
my($this, %param) = @_;
my $class = ref($this) || $this;
my $self = {};
bless($self,$class);
$self->{dbname} = $param{dbname} || File::Spec->catfile($ENV{HOME}, ".notedb");
if(! -e $param{dbname}) {
open(TT,">$param{dbname}") or die "Could not create $param{dbname}: $!\n";
close (TT);
}
elsif(! -w $param{dbname}) {
print "$param{dbname} is not writable!\n";
exit(1);
}
$self->{mtime} = $self->get_stat();
$self->{unread} = 1;
$self->{changed} = 1;
$self->{data} = {};
$self->{LOCKFILE} = $param{dbname} . "~LOCK";
return $self;
}
sub DESTROY {
# clean the desk!
}
sub version {
my $this = shift;
return $NOTEDB::general::VERSION;
}
sub get_stat {
my ($this) = @_;
my $mtime = (stat($this->{dbname}))[9];
return $mtime;
}
sub changed {
my ($this) = @_;
my $current = $this->get_stat();
if ($current > $this->{mtime}) {
$this->{mtime} = $current;
return $current;
}
else {
return 0;
}
}
sub set_del_all {
my $this = shift;
unlink $this->{dbname};
open(TT,">$this->{dbname}") or die "Could not create $this->{dbname}: $!\n";
close (TT);
}
sub get_single {
my($this, $num) = @_;
my($address, $note, $date, $n, $t, $buffer, );
my %data = $this->get_all();
return ($data{$num}->{note}, $data{$num}->{date});
}
sub get_all {
my $this = shift;
my($num, $note, $date, %res);
if ($this->unchanged) {
return %{$this->{cache}};
}
my %data = $this->_retrieve();
foreach my $num (keys %data) {
$res{$num}->{note} = $this->ude($data{$num}->{note});
$res{$num}->{date} = $this->ude($data{$num}->{date});
}
$this->cache(%res);
return %res;
}
sub import_data {
my ($this, $data) = @_;
my %res = $this->_retrieve();
my $pos = (scalar keys %res) + 1;
foreach my $num (keys %{$data}) {
$res{$pos}->{note} = $this->uen($data->{$num}->{note});
$res{$pos}->{date} = $this->uen($data->{$num}->{date});
$pos++;
}
$this->_store(\%res);
}
sub get_nextnum {
my $this = shift;
my($num, $te, $me, $buffer);
if ($this->unchanged) {
$num = 1;
foreach (keys %{$this->{cache}}) {
$num++;
}
return $num;
}
my %data = $this->get_all();
my @numbers = sort { $a <=> $b } keys %data;
$num = pop @numbers;
$num++;
return $num;
}
sub get_search {
my($this, $searchstring) = @_;
my($buffer, $num, $note, $date, %res, $t, $n, $match);
my $regex = $this->generate_search($searchstring);
eval $regex;
if ($@) {
print "invalid expression: \"$searchstring\"!\n";
return;
}
$match = 0;
if ($this->unchanged) {
foreach my $num (keys %{$this->{cache}}) {
$_ = $this->{cache}{$num}->{note};
eval $regex;
if ($match) {
$res{$num}->{note} = $this->{cache}{$num}->{note};
$res{$num}->{date} = $this->{cache}{$num}->{date}
}
$match = 0;
}
return %res;
}
my %data = $this->get_all();
foreach my $num(sort keys %data) {
$_ = $data{$num}->{note};
eval $regex;
if($match)
{
$res{$num}->{note} = $data{$num}->{note};
$res{$num}->{date} = $data{$num}->{data};
}
$match = 0;
}
return %res;
}
sub set_edit {
my($this, $num, $note, $date) = @_;
my %data = $this->_retrieve();
$data{$num} = {
note => $this->uen($note),
date => $this->uen($date)
};
$this->_store(\%data);
$this->changed;
}
sub set_new {
my($this, $num, $note, $date) = @_;
$this->set_edit($num, $note, $date);
}
sub set_del {
my($this, $num) = @_;
my(%data, $note, $date, $T, $setnum, $buffer, $n, $N, $t);
$setnum = 1;
%data = $this->_retrieve();
return "ERROR" if (! exists $data{$num});
delete $data{$num};
$this->_store(\%data);
$this->changed;
return;
}
sub set_recountnums {
my($this) = @_;
my(%orig, %data, $note, $date, $T, $setnum, $buffer, $n, $N, $t);
$setnum = 1;
%orig = $this->_retrieve();
foreach $N (sort {$a <=> $b} keys %orig) {
$data{$setnum} = {
note => $orig{$N}->{note},
date => $orig{$N}->{date}
};
$setnum++;
}
$this->_store(\%data);
$this->changed;
return;
}
sub uen {
my ($this, $raw) = @_;
my($crypted);
if($NOTEDB::crypt_supported == 1) {
eval {
$crypted = $this->{cipher}->encrypt($raw);
};
print $@;
}
else {
$crypted = $raw;
}
my $coded = encode_base64($crypted);
chomp $coded;
return $coded;
}
sub ude {
my ($this, $crypted) = @_;
my($raw);
if($NOTEDB::crypt_supported == 1) {
eval {
$raw = $this->{cipher}->decrypt(decode_base64($crypted));
};
}
else {
$raw = decode_base64($crypted)
}
return $raw;
}
sub _store {
my ($this, $data) = @_;
open NOTE, ">$this->{dbname}" or die "could not open $this->{dbname}: $!\n";
flock NOTE, LOCK_EX;
if (%{$data}) {
my $content = SaveConfigString($data) or die "could not serialize data: $!\n";
print NOTE $content;
}
else {
print NOTE "";
}
flock NOTE, LOCK_UN;
close NOTE;
# finally re-read the db, so that we always have the latest data
$this->_retrieve();
}
sub _retrieve {
my ($this) = @_;
my $file = $this->{dbname};
if (-s $file) {
if ($this->{changed} || $this->{unread}) {
my $fh = new FileHandle "<$this->{dbname}" or die "could not open $this->{dbname}\n";
flock $fh, LOCK_EX;
my %data = ParseConfig(-ConfigFile => $fh) or die "could not read to database: $!\n";
flock $fh, LOCK_UN;
$fh->close();
$this->{unread} = 0;
$this->{data} = \%data;
return %data;
}
else {
return %{$this->{data}};
}
}
else {
return ();
}
}
1; # keep this!
__END__
=head1 NAME
NOTEDB::general - module lib for accessing a notedb from perl
=head1 SYNOPSIS
# include the module
use NOTEDB;
# create a new NOTEDB object
$db = new NOTEDB("text", "/home/tom/.notedb", 4096, 24);
# decide to use encryption
# $key is the cipher to use for encryption
# $method must be either Crypt::IDEA or Crypt::DES
# you need Crypt::CBC, Crypt::IDEA and Crypt::DES to have installed.
$db->use_crypt($key,$method);
# do not use encryption
# this is the default
$db->no_crypt;
# get a single note
($note, $date) = $db->get_single(1);
# search for a certain note
%matching_notes = $db->get_search("somewhat");
# format of returned hash:
#$matching_notes{$numberofnote}->{'note' => 'something', 'date' => '23.12.2000 10:33:02'}
# get all existing notes
%all_notes = $db->get_all();
# format of returnes hash like the one from get_search above
# get the next noteid available
$next_num = $db->get_nextnum();
# modify a certain note
$db->set_edit(1, "any text", "23.12.2000 10:33:02");
# create a new note
$db->set_new(5, "any new text", "23.12.2000 10:33:02");
# delete a certain note
$db->set_del(5);
# turn on encryption. CryptMethod must be IDEA, DES or BLOWFISH
$db->use_crypt("passphrase", "CryptMethod");
# turn off encryption. This is the default.
$db->no_crypt();
=head1 DESCRIPTION
You can use this module for accessing a note database. This backend uses
a text file for storage and Config::General for accessing the file.
Currently, NOTEDB module is only used by note itself. But feel free to use it
within your own project! Perhaps someone want to implement a webinterface to
note...
=head1 USAGE
please see the section SYNOPSIS, it says it all.
=head1 AUTHOR
Thomas Linden <tom@daemon.de>.
=cut

View File

@@ -1,425 +0,0 @@
#
# Perl module for note
# mysql database backend. see docu: perldoc NOTEDB::mysql
#
package NOTEDB::mysql;
$NOTEDB::mysql::VERSION = "1.51";
use DBI;
use strict;
#use Data::Dumper;
use NOTEDB;
use Exporter ();
use vars qw(@ISA @EXPORT);
@ISA = qw(NOTEDB Exporter);
sub new {
my($this, %param) = @_;
my $class = ref($this) || $this;
my $self = {};
bless($self,$class);
my $dbname = $param{dbname} || "note";
my $dbhost = $param{dbhost} || "localhost";
my $dbuser = $param{dbuser} || "";
my $dbpasswd = $param{dbpasswd} || "";
my $dbport = $param{dbport} || "";
my $fnum = "number";
my $fnote = "note";
my $fdate = "date";
my $ftopic = "topic";
my $database;
if ($dbport) {
$database = "DBI:mysql:$dbname;host=$dbhost:$dbport";
}
else {
$database = "DBI:mysql:$dbname;host=$dbhost";
}
$self->{table} = "note";
$self->{sql_getsingle} = "SELECT $fnote,$fdate,$ftopic FROM $self->{table} WHERE $fnum = ?";
$self->{sql_all} = "SELECT $fnum,$fnote,$fdate,$ftopic FROM $self->{table}";
$self->{sql_nextnum} = "SELECT max($fnum) FROM $self->{table}";
$self->{sql_incrnum} = "SELECT $fnum FROM $self->{table} ORDER BY $fnum";
$self->{sql_setnum} = "UPDATE $self->{table} SET $fnum = ? WHERE $fnum = ?";
$self->{sql_edit} = "UPDATE $self->{table} SET $fnote = ?, $fdate = ?, $ftopic = ? WHERE $fnum = ?";
$self->{sql_insertnew} = "INSERT INTO $self->{table} VALUES (?, ?, ?, ?)";
$self->{sql_del} = "DELETE FROM $self->{table} WHERE $fnum = ?";
$self->{sql_del_all} = "DELETE FROM $self->{table}";
$self->{DB} = DBI->connect($database, $dbuser, $dbpasswd) or die DBI->errstr();
return $self;
}
sub DESTROY
{
# clean the desk!
my $this = shift;
$this->{DB}->disconnect;
}
sub lock {
my($this) = @_;
# LOCK the database!
my $lock = $this->{DB}->prepare("LOCK TABLES $this->{table} WRITE")
|| die $this->{DB}->errstr();
$lock->execute() || die $this->{DB}->errstr();
}
sub unlock {
my($this) = @_;
my $unlock = $this->{DB}->prepare("UNLOCK TABLES") || die $this->{DB}->errstr;
$unlock->execute() || die $this->{DB}->errstr();
}
sub version {
my $this = shift;
return $this->{version};
}
sub get_single {
my($this, $num) = @_;
my($note, $date, $topic);
my $statement = $this->{DB}->prepare($this->{sql_getsingle}) || die $this->{DB}->errstr();
$statement->execute($num) || die $this->{DB}->errstr();
$statement->bind_columns(undef, \($note, $date, $topic)) || die $this->{DB}->errstr();
while($statement->fetch) {
$note = $this->ude($note);
if ($topic) {
$note = "$topic\n" . $note;
}
return $note, $this->ude($date);
}
}
sub get_all
{
my $this = shift;
my($num, $note, $date, %res, $topic);
if ($this->unchanged) {
return %{$this->{cache}};
}
my $statement = $this->{DB}->prepare($this->{sql_all}) or die $this->{DB}->errstr();
$statement->execute or die $this->{DB}->errstr();
$statement->bind_columns(undef, \($num, $note, $date, $topic)) or die $this->{DB}->errstr();
while($statement->fetch) {
$res{$num}->{'note'} = $this->ude($note);
$res{$num}->{'date'} = $this->ude($date);
if ($topic) {
$res{$num}->{'note'} = "$topic\n" . $res{$num}->{'note'};
}
}
$this->cache(%res);
return %res;
}
sub get_nextnum
{
my $this = shift;
my($num);
if ($this->unchanged) {
$num = 1;
foreach (keys %{$this->{cache}}) {
$num++;
}
return $num;
}
my $statement = $this->{DB}->prepare($this->{sql_nextnum}) || die $this->{DB}->errstr();
$statement->execute || die $this->{DB}->errstr();
$statement->bind_columns(undef, \($num)) || die $this->{DB}->errstr();
while($statement->fetch) {
return $num+1;
}
}
sub get_search
{
my($this, $searchstring) = @_;
my($num, $note, $date, %res, $match, $use_cache, $topic);
my $regex = $this->generate_search($searchstring);
eval $regex;
if ($@) {
print "invalid expression: \"$searchstring\"!\n";
return;
}
$match = 0;
if ($this->unchanged) {
foreach my $num (keys %{$this->{cache}}) {
$_ = $this->{cache}{$num}->{note};
eval $regex;
if ($match) {
$res{$num}->{note} = $this->{cache}{$num}->{note};
$res{$num}->{date} = $this->{cache}{$num}->{date}
}
$match = 0;
}
return %res;
}
my $statement = $this->{DB}->prepare($this->{sql_all}) or die $this->{DB}->errstr();
$statement->execute or die $this->{DB}->errstr();
$statement->bind_columns(undef, \($num, $note, $date, $topic)) or die $this->{DB}->errstr();
while($statement->fetch) {
$note = $this->ude($note);
$date = $this->ude($date);
if ($topic) {
$note = "$topic\n" . $note;
}
$_ = $note;
eval $regex;
if($match) {
$res{$num}->{'note'} = $note;
$res{$num}->{'date'} = $date;
}
$match = 0;
}
return %res;
}
sub set_edit
{
my($this, $num, $note, $date) = @_;
$this->lock;
my $statement = $this->{DB}->prepare($this->{sql_edit}) or die $this->{DB}->errstr();
$note =~ s/'/\'/g;
$note =~ s/\\/\\\\/g;
$statement->execute($this->uen($note), $this->uen($date), $num)
or die $this->{DB}->errstr();
$this->unlock;
$this->changed;
}
sub set_new
{
my($this, $num, $note, $date) = @_;
$this->lock;
my $statement = $this->{DB}->prepare($this->{sql_insertnew}) || die $this->{DB}->errstr();
my ($topic, $note) = $this->get_topic($note);
$note =~ s/'/\'/g;
$note =~ s/\\/\\\\/g;
$topic =~ s/\\/\\\\/g;
$statement->execute($num, $this->uen($note), $this->uen($date), $topic) || die $this->{DB}->errstr();
$this->unlock;
$this->changed;
}
sub set_del
{
my($this, $num) = @_;
my($note, $date, $T);
$this->lock;
($note, $date) = $this->get_single($num);
return "ERROR" if ($date !~ /^\d/);
# delete record!
my $statement = $this->{DB}->prepare($this->{sql_del}) || die $this->{DB}->errstr();
$statement->execute($num) || die $this->{DB}->errstr();
$this->unlock;
$this->changed;
return;
}
sub set_del_all
{
my($this) = @_;
$this->lock;
my $statement = $this->{DB}->prepare($this->{sql_del_all}) || die $this->{DB}->errstr();
$statement->execute() || die $this->{DB}->errstr();
$this->unlock;
$this->changed;
return;
}
sub set_recountnums {
my $this = shift;
$this->lock;
my(@count, $i, $num, $setnum, $pos);
$setnum = 1;
$pos=0; $i=0; @count = ();
my $statement = $this->{DB}->prepare($this->{sql_incrnum}) || die $this->{DB}->errstr();
$statement->execute || die $this->{DB}->errstr();
$statement->bind_columns(undef, \($num)) || die $this->{DB}->errstr();
# store real id's in an array!
while($statement->fetch) {
$count[$i] = $num;
$i++;
}
# now recount them!
my $sub_statement = $this->{DB}->prepare($this->{sql_setnum}) || die $this->{DB}->errstr();
for($pos=0;$pos<$i;$pos++) {
$setnum = $pos +1;
$sub_statement->execute($setnum,$count[$pos]) || die $this->{DB}->errstr();
}
$this->unlock;
$this->changed;
}
sub import_data {
my ($this, $data) = @_;
foreach my $num (keys %{$data}) {
my $pos = $this->get_nextnum();
$this->set_new($pos, $data->{$num}->{note}, $data->{$num}->{date});
}
}
sub uen
{
my $this = shift;
my($T);
if($NOTEDB::crypt_supported == 1) {
eval {
$T = pack("u", $this->{cipher}->encrypt($_[0]));
};
}
else {
$T = $_[0];
}
chomp $T;
return $T;
}
sub ude
{
my $this = shift;
my($T);
if($NOTEDB::crypt_supported == 1) {
eval {
$T = $this->{cipher}->decrypt(unpack("u",$_[0]))
};
return $T;
}
else {
return $_[0];
}
}
sub get_topic {
my ($this, $data) = @_;
if ($data =~ /^\//) {
my($topic, $note) = split /\n/, $data, 2;
return ($topic, $note);
}
else {
return ("", $data);
}
}
1; # keep this!
__END__
=head1 NAME
NOTEDB::mysql - module lib for accessing a notedb from perl
=head1 SYNOPSIS
# include the module
use NOTEDB;
# create a new NOTEDB object (the last 4 params are db table/field names)
$db = new NOTEDB("mysql","note","localhost","username","password","note","number","note","date");
# get a single note
($note, $date) = $db->get_single(1);
# search for a certain note
%matching_notes = $db->get_search("somewhat");
# format of returned hash:
#$matching_notes{$numberofnote}->{'note' => 'something', 'date' => '23.12.2000 10:33:02'}
# get all existing notes
%all_notes = $db->get_all();
# format of returnes hash like the one from get_search above
# get the next noteid available
$next_num = $db->get_nextnum();
# recount all noteids starting by 1 (usefull after deleting one!)
$db->set_recountnums();
# modify a certain note
$db->set_edit(1, "any text", "23.12.2000 10:33:02");
# create a new note
$db->set_new(5, "any new text", "23.12.2000 10:33:02");
# delete a certain note
$db->set_del(5);
# turn on encryption. CryptMethod must be IDEA, DES or BLOWFISH
$db->use_crypt("passphrase", "CryptMethod");
# turn off encryption. This is the default.
$db->no_crypt();
=head1 DESCRIPTION
You can use this module for accessing a note database. There are currently
two versions of this module, one version for a SQL database and one for a
binary file (note's own database-format).
However, both versions provides identical interfaces, which means, you do
not need to change your code, if you want to switch to another database format.
Currently, NOTEDB module is only used by note itself. But feel free to use it
within your own project! Perhaps someone want to implement a webinterface to
note...
=head1 USAGE
please see the section SYNOPSIS, it says it all.
=head1 AUTHOR
Thomas Linden <tom@daemon.de>.
=cut

View File

@@ -1,612 +0,0 @@
# Perl module for note
# pwsafe3 backend. see docu: perldoc NOTEDB::pwsafe3
package NOTEDB::pwsafe3;
$NOTEDB::pwsafe3::VERSION = "1.08";
use strict;
use Data::Dumper;
use Time::Local;
use Crypt::PWSafe3;
use NOTEDB;
use Fcntl qw(LOCK_EX LOCK_UN);
use Exporter ();
use vars qw(@ISA @EXPORT);
@ISA = qw(NOTEDB Exporter);
sub new {
my($this, %param) = @_;
my $class = ref($this) || $this;
my $self = {};
bless($self,$class);
$self->{dbname} = $param{dbname} || File::Spec->catfile($ENV{HOME}, ".notedb");
$self->{mtime} = $self->get_stat();
$self->{unread} = 1;
$self->{data} = {};
$self->{LOCKFILE} = $param{dbname} . "~LOCK";
$self->{keepkey} = 0;
return $self;
}
sub DESTROY {
# clean the desk!
}
sub version {
my $this = shift;
return $NOTEDB::pwsafe3::VERSION;
}
sub get_stat {
my ($this) = @_;
if(-e $this->{dbname}) {
return (stat($this->{dbname}))[9];
}
else {
return time;
}
}
sub filechanged {
my ($this) = @_;
my $current = $this->get_stat();
if ($current > $this->{mtime}) {
$this->{mtime} = $current;
return $current;
}
else {
return 0;
}
}
sub set_del_all {
my $this = shift;
unlink $this->{dbname};
open(TT,">$this->{dbname}") or die "Could not create $this->{dbname}: $!\n";
close (TT);
}
sub get_single {
my($this, $num) = @_;
my($address, $note, $date, $n, $t, $buffer, );
my %data = $this->get_all();
return ($data{$num}->{note}, $data{$num}->{date});
}
sub get_all {
my $this = shift;
my($num, $note, $date, %res);
if ($this->unchanged) {
return %{$this->{cache}};
}
my %data = $this->_retrieve();
foreach my $num (keys %data) {
($res{$num}->{date}, $res{$num}->{note}) = $this->_pwsafe3tonote($data{$num}->{note});
}
$this->cache(%res);
return %res;
}
sub import_data {
my ($this, $data) = @_;
my $fh;
if (-s $this->{dbname}) {
$fh = new FileHandle "<$this->{dbname}" or die "could not open $this->{dbname}\n";
flock $fh, LOCK_EX;
}
my $key = $this->_getpass();
eval {
my $vault = new Crypt::PWSafe3(password => $key, file => $this->{dbname});
foreach my $num (keys %{$data}) {
my $checksum = $this->get_nextnum();
my %record = $this->_notetopwsafe3($checksum, $data->{$num}->{note}, $data->{$num}->{date});
my $rec = new Crypt::PWSafe3::Record();
$rec->uuid($record{uuid});
$vault->addrecord($rec);
$vault->modifyrecord($record{uuid}, %record);
}
$vault->save();
};
if ($@) {
print "Exception caught:\n$@\n";
exit 1;
}
eval {
flock $fh, LOCK_UN;
$fh->close();
};
$this->{keepkey} = 0;
$this->{key} = 0;
}
sub get_nextnum {
my $this = shift;
my($num, $te, $me, $buffer);
my $ug = new Data::UUID;
$this->{nextuuid} = unpack('H*', $ug->create());
$num = $this->_uuid( $this->{nextuuid} );
return $num;
}
sub get_search {
my($this, $searchstring) = @_;
my($buffer, $num, $note, $date, %res, $t, $n, $match);
my $regex = $this->generate_search($searchstring);
eval $regex;
if ($@) {
print "invalid expression: \"$searchstring\"!\n";
return;
}
$match = 0;
if ($this->unchanged) {
foreach my $num (keys %{$this->{cache}}) {
$_ = $this->{cache}{$num}->{note};
eval $regex;
if ($match) {
$res{$num}->{note} = $this->{cache}{$num}->{note};
$res{$num}->{date} = $this->{cache}{$num}->{date}
}
$match = 0;
}
return %res;
}
my %data = $this->get_all();
foreach my $num(sort keys %data) {
$_ = $data{$num}->{note};
eval $regex;
if($match)
{
$res{$num}->{note} = $data{$num}->{note};
$res{$num}->{date} = $data{$num}->{data};
}
$match = 0;
}
return %res;
}
sub set_edit {
my($this, $num, $note, $date) = @_;
my %data = $this->_retrieve();
my %record = $this->_notetopwsafe3($num, $note, $date);
if (exists $data{$num}) {
$data{$num}->{note} = \%record;
$this->_store(\%record);
}
else {
%record = $this->_store(\%record, 1);
}
$this->changed;
}
sub set_new {
my($this, $num, $note, $date) = @_;
$this->set_edit($num, $note, $date);
}
sub set_del {
my($this, $num) = @_;
my $uuid = $this->_getuuid($num);
if(! $uuid) {
print "Note $num does not exist!\n";
return;
}
my $fh = new FileHandle "<$this->{dbname}" or die "could not open $this->{dbname}\n";
flock $fh, LOCK_EX;
my $key = $this->_getpass();
eval {
my $vault = new Crypt::PWSafe3(password => $key, file => $this->{dbname});
delete $vault->{record}->{$uuid};
$vault->markmodified();
$vault->save();
};
if ($@) {
print "Exception caught:\n$@\n";
exit 1;
}
eval {
flock $fh, LOCK_UN;
$fh->close();
};
# finally re-read the db, so that we always have the latest data
$this->_retrieve($key);
$this->changed;
return;
}
sub set_recountnums {
my($this) = @_;
# unsupported
return;
}
sub _store {
my ($this, $record, $create) = @_;
my $fh;
if (-s $this->{dbname}) {
$fh = new FileHandle "<$this->{dbname}" or die "could not open $this->{dbname}\n";
flock $fh, LOCK_EX;
}
my $key;
my $prompt = "pwsafe password: ";
foreach my $try (1..5) {
if($try > 1) {
$prompt = "pwsafe password ($try retry): ";
}
$key = $this->_getpass($prompt);
eval {
my $vault = new Crypt::PWSafe3(password => $key, file => $this->{dbname});
if ($create) {
my $rec = new Crypt::PWSafe3::Record();
$rec->uuid($record->{uuid});
$vault->addrecord($rec);
$vault->modifyrecord($record->{uuid}, %{$record});
}
else {
$vault->modifyrecord($record->{uuid}, %{$record});
}
$vault->save();
};
if ($@) {
if($@ =~ /wrong pass/i) {
$key = '';
next;
}
else {
print "Exception caught:\n$@\n";
exit 1;
}
}
else {
last;
}
}
eval {
flock $fh, LOCK_UN;
$fh->close();
};
if(!$key) {
print STDERR "Giving up after 5 failed password attempts.\n";
exit 1;
}
# finally re-read the db, so that we always have the latest data
$this->_retrieve($key);
}
sub _retrieve {
my ($this, $key) = @_;
my $file = $this->{dbname};
if (-s $file) {
if ($this->filechanged() || $this->{unread}) {
my %data;
if (! $key) {
$key = $this->_getpass();
}
eval {
my $vault = new Crypt::PWSafe3(password => $key, file => $this->{dbname});
my @records = $vault->getrecords();
foreach my $record (sort { $a->ctime <=> $b->ctime } @records) {
my $num = $this->_uuid( $record->uuid );
my %entry = (
uuid => $record->uuid,
title => $record->title,
user => $record->user,
passwd => $record->passwd,
notes => $record->notes,
group => $record->group,
lastmod=> $record->lastmod,
ctime => $record->ctime,
);
$data{$num}->{note} = \%entry;
}
};
if ($@) {
print "Exception caught:\n$@\n";
exit 1;
}
$this->{unread} = 0;
$this->{data} = \%data;
return %data;
}
else {
return %{$this->{data}};
}
}
else {
return ();
}
}
sub _pwsafe3tonote {
#
# convert pwsafe3 record to note record
my ($this, $record) = @_;
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($record->{ctime});
my $date = sprintf("%02d.%02d.%04d %02d:%02d:%02d", $mday, $mon+1, $year+1900, $hour, $min, $sec);
chomp $date;
my $note;
if ($record->{group}) {
my $group = $record->{group};
# convert group separator
$group =~ s#\.#/#g;
$note = "/$group/\n";
}
# pwsafe3 uses windows newlines, so convert ours
$record->{notes} =~ s/\r\n/\n/gs;
#
# we do NOT add user and password fields here extra
# because if it is contained in the note, from were
# it was extracted initially, where it remains anyway
$note .= "$record->{title}\n$record->{notes}";
return ($date, $note);
}
sub _notetopwsafe3 {
#
# convert note record to pwsafe3 record
# only used on create or save
#
# this one is the critical part, because the two
# record types are fundamentally incompatible.
# we parse our record and try to guess the values
# required for pwsafe3
#
# expected input for note:
# /path/ -> group, optional
# any text -> title
# User: xxx -> user
# Password: xxx -> passwd
# anything else -> notes
#
# expected input for date:
# 23.02.2010 07:56:27
my ($this, $num, $text, $date) = @_;
my ($group, $title, $user, $passwd, $notes, $ts, $content);
if ($text =~ /^\//) {
($group, $title, $content) = split /\n/, $text, 3;
}
else {
($title, $content) = split /\n/, $text, 2;
}
if(!defined $content) { $content = ""; }
if(!defined $group) { $group = ""; }
$user = $passwd = '';
if ($content =~ /(user|username|login|account|benutzer):\s*(.+)/i) {
$user = $2;
}
if ($content =~ /(password|pass|passwd|kennwort|pw):\s*(.+)/i) {
$passwd = $2;
}
# 1 2 3 4 5 6
if ($date =~ /^(\d\d)\.(\d\d)\.(\d{4}) (\d\d):(\d\d):(\d\d)$/) {
# timelocal($sec,$min,$hour,$mday,$mon,$year);
$ts = timelocal($6, $5, $4, $1, $2-1, $3-1900);
}
# make our topics pwsafe3 compatible groups
$group =~ s#^/##;
$group =~ s#/$##;
$group =~ s#/#.#g;
# pwsafe3 uses windows newlines, so convert ours
$content =~ s/\n/\r\n/gs;
my %record = (
uuid => $this->_getuuid($num),
user => $user,
passwd => $passwd,
group => $group,
title => $title,
ctime => $ts,
lastmod=> $ts,
notes => $content,
);
return %record;
}
sub _uuid {
my ($this, $uuid) = @_;
if (exists $this->{uuidnum}->{$uuid}) {
return $this->{uuidnum}->{$uuid};
}
my $max = 0;
if (exists $this->{numuuid}) {
$max = (sort { $b <=> $a } keys %{$this->{numuuid}})[0];
}
my $num = $max + 1;
$this->{uuidnum}->{$uuid} = $num;
$this->{numuuid}->{$num} = $uuid;
return $num;
}
sub _getuuid {
my ($this, $num) = @_;
return $this->{numuuid}->{$num};
}
sub _getpass {
#
# We're doing this here ourselfes
# because the note way of handling encryption
# doesn't work with pwsafe3, we can't hold a cipher
# structure in memory, because pwsafe3 handles this
# itself.
# Instead we ask for the password everytime we want
# to fetch data from the actual file OR want to write
# to it. To minimize reads, we use caching by default.
my($this, $prompt) = @_;
if ($this->{key}) {
return $this->{key};
}
else {
my $key;
print STDERR $prompt ? $prompt : "pwsafe password: ";
eval {
local($|) = 1;
local(*TTY);
open(TTY,"/dev/tty") or die "No /dev/tty!";
system ("stty -echo </dev/tty") and die "stty failed!";
chomp($key = <TTY>);
print STDERR "\r\n";
system ("stty echo </dev/tty") and die "stty failed!";
close(TTY);
};
if ($@) {
$key = <>;
}
if ($this->{keepkey}) {
$this->{key} = $key;
}
return $key;
}
}
1; # keep this!
__END__
=head1 NAME
NOTEDB::pwsafe3 - module lib for accessing a notedb from perl
=head1 SYNOPSIS
# include the module
use NOTEDB;
# create a new NOTEDB object
$db = new NOTEDB("text", "/home/tom/.notedb", 4096, 24);
# decide to use encryption
# $key is the cipher to use for encryption
# $method must be either Crypt::IDEA or Crypt::DES
# you need Crypt::CBC, Crypt::IDEA and Crypt::DES to have installed.
$db->use_crypt($key,$method);
# do not use encryption
# this is the default
$db->no_crypt;
# get a single note
($note, $date) = $db->get_single(1);
# search for a certain note
%matching_notes = $db->get_search("somewhat");
# format of returned hash:
#$matching_notes{$numberofnote}->{'note' => 'something', 'date' => '23.12.2000 10:33:02'}
# get all existing notes
%all_notes = $db->get_all();
# format of returnes hash like the one from get_search above
# get the next noteid available
$next_num = $db->get_nextnum();
# modify a certain note
$db->set_edit(1, "any text", "23.12.2000 10:33:02");
# create a new note
$db->set_new(5, "any new text", "23.12.2000 10:33:02");
# delete a certain note
$db->set_del(5);
# turn on encryption. CryptMethod must be IDEA, DES or BLOWFISH
$db->use_crypt("passphrase", "CryptMethod");
# turn off encryption. This is the default.
$db->no_crypt();
=head1 DESCRIPTION
You can use this module for accessing a note database. This backend uses
a text file for storage and Config::General for accessing the file.
Currently, NOTEDB module is only used by note itself. But feel free to use it
within your own project! Perhaps someone want to implement a webinterface to
note...
=head1 USAGE
please see the section SYNOPSIS, it says it all.
=head1 AUTHOR
Thomas Linden <tom AT linden DOT at>
=cut

View File

@@ -1,352 +0,0 @@
# Perl module for note
# text database backend. see docu: perldoc NOTEDB::text
# using Storable as backend.
package NOTEDB::text;
$NOTEDB::text::VERSION = "1.04";
use strict;
#use Data::Dumper;
use File::Spec;
use Storable qw(lock_nstore lock_retrieve);
use MIME::Base64;
use NOTEDB;
use Fcntl qw(LOCK_EX LOCK_UN);
use Exporter ();
use vars qw(@ISA @EXPORT);
@ISA = qw(NOTEDB Exporter);
sub new {
my($this, %param) = @_;
my $class = ref($this) || $this;
my $self = {};
bless($self,$class);
$self->{NOTEDB} = $self->{dbname} = $param{dbname} || File::Spec->catfile($ENV{HOME}, ".notedb");
if(! -e $param{dbname}) {
open(TT,">$param{dbname}") or die "Could not create $param{dbname}: $!\n";
close (TT);
}
elsif(! -w $param{dbname}) {
print "$param{dbname} is not writable!\n";
exit(1);
}
$self->{LOCKFILE} = $param{dbname} . "~LOCK";
$self->{mtime} = $self->get_stat();
$self->{unread} = 1;
$self->{data} = {};
return $self;
}
sub DESTROY
{
# clean the desk!
}
sub version {
my $this = shift;
return $NOTEDB::text::VERSION;
}
sub get_stat {
my ($this) = @_;
my $mtime = (stat($this->{dbname}))[9];
return $mtime;
}
sub set_del_all {
my $this = shift;
unlink $this->{NOTEDB};
open(TT,">$this->{NOTEDB}") or die "Could not create $this->{NOTEDB}: $!\n";
close (TT);
}
sub get_single {
my($this, $num) = @_;
my($address, $note, $date, $n, $t, $buffer, );
my %data = $this->get_all();
return ($data{$num}->{note}, $data{$num}->{date});
}
sub get_all {
my $this = shift;
my($num, $note, $date, %res);
if ($this->unchanged) {
return %{$this->{cache}};
}
my %data = $this->_retrieve();
foreach my $num (keys %data) {
$res{$num}->{note} = $this->ude($data{$num}->{note});
$res{$num}->{date} = $this->ude($data{$num}->{date});
}
$this->cache(%res);
return %res;
}
sub import_data {
my ($this, $data) = @_;
my %res = $this->_retrieve();
my $pos = (scalar keys %res) + 1;
foreach my $num (keys %{$data}) {
$res{$pos}->{note} = $this->uen($data->{$num}->{note});
$res{$pos}->{date} = $this->uen($data->{$num}->{date});
$pos++;
}
$this->_store(\%res);
}
sub get_nextnum {
my $this = shift;
my($num, $te, $me, $buffer);
if ($this->unchanged) {
my @numbers = sort { $a <=> $b } keys %{$this->{cache}};
$num = pop @numbers;
$num++;
return $num;
}
my %data = $this->get_all();
my @numbers = sort { $a <=> $b } keys %data;
$num = pop @numbers;
$num++;
return $num;
}
sub get_search {
my($this, $searchstring) = @_;
my($buffer, $num, $note, $date, %res, $t, $n, $match);
my $regex = $this->generate_search($searchstring);
eval $regex;
if ($@) {
print "invalid expression: \"$searchstring\"!\n";
return;
}
$match = 0;
if ($this->unchanged) {
foreach my $num (keys %{$this->{cache}}) {
$_ = $this->{cache}{$num}->{note};
eval $regex;
if ($match) {
$res{$num}->{note} = $this->{cache}{$num}->{note};
$res{$num}->{date} = $this->{cache}{$num}->{date}
}
$match = 0;
}
return %res;
}
my %data = $this->get_all();
foreach my $num(sort keys %data) {
$_ = $data{$num}->{note};
eval $regex;
if($match)
{
$res{$num}->{note} = $data{$num}->{note};
$res{$num}->{date} = $data{$num}->{data};
}
$match = 0;
}
return %res;
}
sub set_edit {
my($this, $num, $note, $date) = @_;
my %data = $this->_retrieve();
$data{$num} = {
note => $this->uen($note),
date => $this->uen($date)
};
$this->_store(\%data);
$this->changed;
}
sub set_new {
my($this, $num, $note, $date) = @_;
$this->set_edit($num, $note, $date);
}
sub set_del {
my($this, $num) = @_;
my(%data, $note, $date, $T, $setnum, $buffer, $n, $N, $t);
$setnum = 1;
%data = $this->_retrieve();
return "ERROR" if (! exists $data{$num});
delete $data{$num};
$this->_store(\%data);
$this->changed;
return;
}
sub set_recountnums {
# not required here
return;
}
sub uen {
my ($this, $raw) = @_;
my($crypted);
if($NOTEDB::crypt_supported == 1) {
eval {
$crypted = $this->{cipher}->encrypt($raw);
};
}
else {
$crypted = $raw;
}
my $coded = encode_base64($crypted);
return $coded;
}
sub ude {
my ($this, $crypted) = @_;
my($raw);
if($NOTEDB::crypt_supported == 1) {
eval {
$raw = $this->{cipher}->decrypt(decode_base64($crypted));
};
}
else {
$raw = decode_base64($crypted)
}
return $raw;
}
sub _store {
my ($this, $data) = @_;
lock_nstore($data, $this->{NOTEDB});
}
sub _retrieve {
my $this = shift;
if (-s $this->{NOTEDB}) {
if ($this->changed() || $this->{unread}) {
my $data = lock_retrieve($this->{NOTEDB});
$this->{unread} = 0;
$this->{data} = $data;
return %{$data};
}
}
else {
return ();
}
}
1; # keep this!
__END__
=head1 NAME
NOTEDB::text - module lib for accessing a notedb from perl
=head1 SYNOPSIS
# include the module
use NOTEDB;
# create a new NOTEDB object
$db = new NOTEDB("text", "/home/tom/.notedb", 4096, 24);
# decide to use encryption
# $key is the cipher to use for encryption
# $method must be either Crypt::IDEA or Crypt::DES
# you need Crypt::CBC, Crypt::IDEA and Crypt::DES to have installed.
$db->use_crypt($key,$method);
# do not use encryption
# this is the default
$db->no_crypt;
# get a single note
($note, $date) = $db->get_single(1);
# search for a certain note
%matching_notes = $db->get_search("somewhat");
# format of returned hash:
#$matching_notes{$numberofnote}->{'note' => 'something', 'date' => '23.12.2000 10:33:02'}
# get all existing notes
%all_notes = $db->get_all();
# format of returnes hash like the one from get_search above
# get the next noteid available
$next_num = $db->get_nextnum();
# modify a certain note
$db->set_edit(1, "any text", "23.12.2000 10:33:02");
# create a new note
$db->set_new(5, "any new text", "23.12.2000 10:33:02");
# delete a certain note
$db->set_del(5);
# turn on encryption. CryptMethod must be IDEA, DES or BLOWFISH
$db->use_crypt("passphrase", "CryptMethod");
# turn off encryption. This is the default.
$db->no_crypt();
=head1 DESCRIPTION
You can use this module for accessing a note database. This backend uses
a text file for storage and Storable for accessing the file.
Currently, NOTEDB module is only used by note itself. But feel free to use it
within your own project! Perhaps someone want to implement a webinterface to
note...
=head1 USAGE
please see the section SYNOPSIS, it says it all.
=head1 AUTHOR
Thomas Linden <tom@daemon.de>.
=cut

View File

@@ -1,74 +0,0 @@
README for the mysql database installation for note
Requirements
============
You need the following things:
o perl installed (5.004x)
o mysql database installed and running
o Mysql perlmodule (you can find it on
http://www.mysql.org) PLEASE NOTE:
It needs the Module "Mysql". The install.sh
script will install it for you directly from
CPAN if you like. Newer versions
are DBI, which you can also use to access
mysql databases. If you want to use it, you
have to rewrite the program. Please let me
know, if you did it :-)
o permissions to create a new database and
to write data to this database.
Installation
============
First, make sure all these things above are ok.
You can use the script "install.sh" to create a new
database and the table structure. You might edit
the script before running it.
If you are getting trouble, i.e. if you have not the
required permissions to do that, please make sure,
you can.
As user root, you have to give your user the
neccessary permissions. Please refer to the mysql
documentation, how to do that.
After that repeat the step above.
You can find a sample config file within the subdirectory
"config" named noterc. There are some special values
which you can use to connect to a different database
then the default.
install.sh will create the following database:
name: user_note
Maintable: note
Number: number(int 10)
Note: note(text)
Date: date(text)
You can use the file "permissions" as a template for
modifying a users permissions to her database. Please
note, that there are different version of mysql out
there with different access privilege systems, which
are not compatible, refer to the documentation shipped
with your mysql installation to learn, how many fields
are available and what they are for.
You may also take a look to:
http://www.mysql.org/Manual_chapter/manual_Privilege_system.html
This should be all.
Manual Installation
===================
1) create a mysql database
mysqladmin create $db
2) add the required GRANT to a user and database
echo "GRANT ALL PRIVILEGES ON $db TO $user@localhost IDENTIFIED BY '$password'" | mysql mysql
3) create the schema:
mysql $db < sql

View File

@@ -1,33 +0,0 @@
#!/bin/sh
# installs note
# This is the installer for the mysql version only!
echo "Welcome to note `cat ../VERSION` installation."
echo "the install script will ask you a view questions,"
echo "make sure to answer them correctly!"
echo
/bin/echo -n "creating the note database..."
NAME="_note"
DBNAME="$USER$NAME"
echo "DBNAME=$DBNAME"
mysqladmin create $DBNAME
echo "done."
/bin/echo -n "creating the table structure using defaults..."
mysql $DBNAME < sql
echo "Shall I try to install the required MySQL driver from CPAN?"
read YESNO
case $YESNO in
"y" | "Y")
if [ $(id -ru) != 0 ] ; then
echo "You should be root for that!"
exit
fi
perl -MCPAN -e shell cpan> install mysql
;;
esac
echo "done."

View File

@@ -1,2 +0,0 @@
insert into user values
('localhost','','','Y','Y','Y','Y','Y','Y','N','N','N','N','N','N','N','Y');

View File

@@ -1,9 +0,0 @@
CREATE TABLE note (
number int(10) DEFAULT '0' NOT NULL auto_increment,
topic text,
note text,
date text,
PRIMARY KEY (number)
);
# sample grant statement:
#GRANT ALL PRIVILEGES ON tom_note TO tom@localhost IDENTIFIED BY 'password';

539
note.pod
View File

@@ -1,539 +0,0 @@
# -*-perl-*-
=head1 NAME
note - a perl script for maintaining notes.
=head1 SYNPOPSIS
note [options] [ number [,number...]]
=head1 DESCRIPTION
B<note> is a small console program written in perl, which allows
you to manage notes similar to programs like "knotes" but from
the commandline. Note can use different database-backends for
notes-storage. It ships with a DBI-based mysql-module(which
can also be used for other by DBI supported DBMS), another
module, which uses a binary file for storage and a DBM module.
There are also two modules available which uses a text file.
Note supports since version 1.0.0 encryption(IDEA or DES)!
=head1 OPTIONS
=over
=item I<-c, --config file>
Use another config file than the default ~/.noterc.
=item I<-l, --list [topic]>
Lists all existing notes. If no topic were specified,
it will display a list of all existing topics.
See the section I<TOPICS> for details about topics.
=item I<-L, --longlist [topic]>
The same as I<-l> but prints also the timestamp of the notes.
=item I<-t, --topic>
Prints a list of all topics as a tree.
=item I<-T, --longtopic>
Prints the topic-tree with the notes under each topic.
=item I<-s, --search string>
Searches for <string> trough the notes database. See the section
I<SEARCHING> for details about the search engine.
=item I<-e, --edit number>
Edit the note with the number <number> using your default editor
or the one you specified in the config file.
=item I<-d, --delete number>
Delete the note with the number <number>. You can delete multiple notes
with one command. "1-4" deletes the notes 1,2,3,4. And "1,5,7" deletes
the specified ones.
=item I<-D, --Dump [file | -]>
Dumps all notes to the textfile <file>. If <file> is a "-" it will
be printed out to standard output (STDOUT).
=item I<-I, --Import file | ->
Imports a previously dumped textfile into the
note database. Data will be appended by default.
You can also specify a dash I<note -I -> instead of a <file>,
which causes note, silently to read in a dump from STDIN.
=item I<-o, --overwrite>
Only suitable for use with --Import. Overwrites an
existing notedb. Use with care.
=item I<-r, --raw>
Raw mode, output will not be formatted. Works not in interactive
mode, only on cmd-line for list and display. That means, no colors
will be used and no lines or titles.
=item I<-i, --interactive>
Start note in interactive mode. See the section I<INTERACTIVE MODE>
for details on this mode.
=item I<--encrypt cleartext>
Encrypt the given clear text string. You would need that if you want to
store the mysql password not in cleartext in the config(if you are using
the mysql backend!).
=item I<-h, --help>
Display this help screen.
=item I<-v, --version>
Display the version number.
=item B<->
If you run note just with one dash: B<note ->, then it will read in a new
note from STDIN until EOF. This makes it possible to pipe text into a new note, i.e.:
cat sometextfile | note -
=back
=head1 USAGE
=head2 GENERAL USAGE
If you don't know, how to run note, try "note -h" first.
It will tell you all available commandline options.
To create a new note, simply run "note". You can enter
the note (the length is by default limited to 4096 bytes,
which you can change from your config file if you are using
the binary backend, otherwise there is no limitation).
End by typing a . on a line itself. note will tell you the
number of the note.
If you want to view the note, type "note 1", if the notenumber
was 1.
If you want to get an overview of all notes, type "note -l".
You will get a list of all notes, containing the number,
the first line and the creation date. If topic-support is
turned on (which is by default), then all subtopics under the
current topic will be displayed first.
If you want to see the timestamps, use "-L" instead of "-l".
Read more about topics below in the section "Topics".
You can also specify the topic which notes you want to see:
"-l mytopic" does the trick.
Additional, you might want to get an overview of your topic-
structure. You can use the command "-t" in this case, which
will display a tree-view of your topic-structure. You can
use the command "-T" if you want to see the notes under each
topic too. "-T" will also show the number of each note.
To edit a certain note, type "note -e 1". It will invoke your
editor (vi or pico). You can edit it, after saving, note
will store the changed note to the database.
Of course you can drop a certain note: "note -d 1" deletes
note number 1. If a note in the middle or the beginning of
the database will be deleted, note will recount the other
existent notes. For example there are 3 notes, number 1, 2
and 3. If you delete number 2, then number 3 will become
number 2.
You can also make use of the extended delete-syntax:
To delete note 1 and 2, use "-d 1,2"
To delete note 1,2 and 3, use "-d 1-3".
=head2 SEARCHING
If you cannot remember, which note you are looking for, you
can use the search capability of note: "note -s <searchstring>".
note will search the whole note database case insensitive for
an occurence of this string and tell you the number and first-
line it has.
You can extend the searchstring using B<AND>, B<OR> ( and ) and
shell-like wildcards:
$ note -s "moses AND lenin"
or:
$ note -s "(mike OR arnold) AND (jackson OR schwarzenegger)"
If note finds a note, which first line is a topic, then it will
display it's second line.
These rules apply for the interactive search too.
You need to know, that note searches for the expression in every
note. In other words, "moses AND lenin" searches for an occurence
of "moses" and "lenin" in ONE note. Or, if you are looking for
"mike OR daniel", then it searches for an occurence of "mike" or
daniel" in ONE note. Thus a note with the text "mike oldfield" will
match that search.
=head2 TOPICS
If topic-support is turned on (which is by default), the various
notes are sorted under various topics. There is no special database
field for the topic. Instead the topic will be stored right in the
note.
If the first line of your note contains some text bordered by slashes
(or whatever you prefer, set "TopicSeparator" in your config! default
is slash), then note will consider it as the topic of this certain
note. For examle:
B</TodoList/>
If you are using topics, no data after the topic is allowed, if there
is any text, note will consider it as a subtopic! Therefore, don't for-
get to put a newline after the topic-line.
The list-command will only show you notes under this topic. If you
create a new note, it will automagically inserted under the current
topic (note will prepend the string "/topicname/" to the text of your
note).
You can create at any time from any point a new topic. Just create a new
note and type the name of the new topic bordered by slashes (or
TopicSeparator) at the first line of this note. After saving, there
will be available a new topic with one note in it.
You can create as many subtopics as you like, the format is similar to
a filesystem-path. An example, say, you want to create such a
structure:
(root - top level)
|
|----test
| |----subtopic
| | |--note 1
| | |--note 2
| |
| |--note 4
|
|--note 3
Then you may create those 4 new notes:
--- snip ---
/test/subtopic/
note 1
--- snip ---
/test/subtopic/
note 2
--- snip ---
note 3
--- snip ---
/test/
note 4
--- snip ---
I hope, you got the point ;-)
If a note does not contain the "magic" /topic/ construction on the first
line, it will be listed under the "root" of note, that is the point
you are at the startup of note.
You can subsequently move a note without a topic to a certain topic.
Simply edit it and insert at the first line the above mentioned
construction.
Note: Please don't forget the prepending and appending a slash of a
topic. You will get strange results without it!
=head2 INTERACTIVE MODE
If you start note with the commandline flag B<-i>, then it starts
with an interactive interface.
It will start with a listing under the default top-topic ("/").
You can enter the name of a topic to change to that topic. This works
similar to a filesystem structure. The current topic will be
displayed on the top of the screen.
The following commands are available:
=over
=item B<L [topic]>
This command lists all notes with a timestamp. If you specify a topic, it
will only list the notes under this topic. If you are under a certain subtopic,
then it will only display the notes under this topic.
=item B<l [topic]>
This commands behaves similar to B<L> but it does not display the timestamp.
You can achieve the same result by simply pressing enter at any time.
=item B<N>
You can create a new note by simply pressing B<N> or B<n>. You favorite
editor will be started and you can enter your note text. If you are already
under a topic then this new note will automatically go to this topic.
note adds an aditional line to the top of the note with the topic. But
you can of course specify your own topic.
Note will tell you which number it has assigned to the newly created note.
=item B<E number>
By entering B<E> or B<e> and a note-number you can edit an existing note
using your favorite editor. This way you can also move an existing note
from one topic to another one by editing the first line of the note.
=item B<D number>
B<E> or B<e> deletes one or more existing note(s). It requires a note number
or a set of note numbers. 1-5 and 1,7,9 are possible values.
After one or more notes has been deleted note will recount all remaining notes.
Say if you delete 1 and 2, then 3 will become 1, 4 will become 5 and so forth.
=item B<S [expression]>
You can search for the occurence of a text in your notes-database with the
command B<S> or B<s>. If you omit an expression note will ask you for one.
If your search criteria matches on exactly one entry, note will display
that note entry instead of displaying its number.
=item B<T>
This prints a tree-view of your topic-structure. B<T> displays the tree with
notes, B<t> displays just the topics without notes.
=item B<C>
It is possible to change note's behavior at runtime. Specify the parameter
you'd like to modify followed by equalsign and the new value. Use with
care! However, database related parameters cannot be changed at runtime.
Entering just "c" without parameters displays the customizable variables.
=item B<cd topic>
Change the actual topic under which you are. This works identical like just
entering the topic but it has some advantages. You can enter B<cd ..> if
you want to go one level up in the topic-structure. And you can enter B<cd />
to go to the top of the structure. You can always leave out the 'cd' keyword too.
Additional it is possible to enter a note-number instead of a topic name.
For this feature to be active you need to set the config option B<ShortCd>
to B<1> or B<yes>. If you use a number and the note with this number is
under a certain topic then you will "cd" to this topic. This allows you
to do kind of jumps over multiple levels of topics.
If is possible to abbreviate a topic. This works only if the abbreviation
matches on one single topic. If it matches more than one topic then the
available ones will be suggested.
=item B<? or h>
Display a short help screen.
=item B<Q>
Quit note.
=back
=head2 BACKUP
You can also dump the contents of your note-database into a
ASCII-textfile(I<-D>). You can use this file later to import it into
your note-database(-I). This is usefull, if you want quickly trans-
fer your notes from one host to another (i.e. you could mail
your note-dump form your office to home and import it there
for further use).
The dumps from the two versions of note are in the same format.
Using dumps it is also possible to reinitialize your database. You
can use the "-o" switch whcih causes note to overwrite your existing
database. This is very handy if you changed heavily your config. And
it is required, if you changed: encryption, db-driver, (binary-format)
and the password. You can use the following command for reinitializing:
$ note -D - | note -o -I -
What the hell, does this do?! Step by step:
=over
=item *
B<note -D -> creates a note-database dump and prints it out
to stantdard output.
=item *
B<|> this is the shell's pipe command. It takes the output
of the left program and gives it to the right program as
standard input.
=item *
B<note -o -I -> imports a note-database dump from standard
input and overwrites an existing database.
=back
Before you use the B<-o> switch, I consider you to make a backup!
=head3 BACKUP FILE FORMAT
B<Caution>: since version 1.3.8 note uses a new file format
for backups: YAML. The old format is only supported by the
B<-I> option to import old backups. New backups are always
created as YAML files. See L<YAML>.
=head2 FORMATING
Another very nice feature is the possibility to format the note-text
(as much as shell allows it). First, you can use the note-internal
"magic-strings" for colorizing. Those strings looks much like HTML:
"<green>here is a green line of text</green> no more green."
As you see, the beginning of another color starts with a tag(kinda) of
the color <colorname> and ends with an end tag </colorname>.
The following colors are available:
black, red, green, yellow, blue, magenta, cyan and white.
Beside colorizing text, you can also create bold or underlined text! If
you decide to use this (additional) feature, you need to set the
Config-Option "FormatText" to 1 which turns it on.
Usage is very straightforward, if a word (a word is defined as some
text with at least one space surrounded) is between a magic mark-
character. Here are the available things, you can do:
bold: **word**
underlined: __word__
inverse: {{word}}
hidden: //word//
The text will be formatted using the actually note-color.
The hidden formatting will use blue forground and blue background
to hide a string from the terminal, which is usefull for passwords.
If you set "FormatText" to I<simple> then the formatting can be
done this way instead:
bold: *word*
underlined: _word_
inverse: {word}
hidden: /word/
=head1 ENCRYPTION
You can turn on encryption from the config file.
Simply set UseEncryption to 1. Please note, that you need
to decide, if you want to use encryption before the first use
of note! If have already a note database and want to "migrate"
to encryption, I suggest you to follow the directions in the
file UPGRADE!
You can choose from different encryption algorythms. The default
is IDEA, but DES or BLOWFISH are also possible. You need to have
installed the following additional perl-modules on your system:
MD5
Crypt::IDEA
Crypt::DES
Crypt::CBC
After turning on encryption, note will ask you for a passphrase
everytime it runs! It will *not* store this passphrase!
So, don't forget it! Be careful!
=head1 CONFIGURATION
You can use a configuration file with note but it is not required.
Note will use default values if there is no config.
The default config file is B<~/.noterc>. You may specify another
one with the commandline flag I<--config>.
Comments start with #, empty lines will be ignored.
To turn on an option, set it to: B<1>, B<on> or B<yes>.
To turn off an option, set it to: B<0>, B<off> or B<no>.
An option consists of an atribute-value pair separated
by minimum one space (more spaces and/or tabs are allowed)
and an optional equal sign in between.
Variable names are case in-sensitive.
For a detailed explanation of each possible parameter take a look
at the supplied sample configuration file in B<config/noterc>.
=head1 AUTHOR
T.v.Dein <tlinden@cpan.org>
=head1 VERSION
1.3.20
=cut

135
t/run.t
View File

@@ -1,135 +0,0 @@
# -*-perl-*-
#use Test::More tests => 8;
use Test::More qw(no_plan);
use Data::Dumper;
my $expect = {
1 => {
'date' => '23.12.2000 10:33:02',
'note' => 'any new text'
},
2 => {
'date' => '03.02.2004 18:13:52',
'note' => 'yet whatever you mean'
}
};
BEGIN { use_ok "NOTEDB" };
require_ok("NOTEDB");
my $key = '01010101';
my $alg = 'Rijndael';
foreach my $CR (1 .. 0) {
$NOTEDB::crypt_supported = $CR;
SKIP: {
skip "no crypt", 1 if $CR; # FIXME: for some weird reason, crypto doesn't work with ::binary?
eval { require NOTEDB::binary; };
skip "Fatal, skipping test for NOTEDB::binary", 1 if $@;
unlink "t/binary.out";
my $db = new NOTEDB::binary(dbname => "t/binary.out");
$db->use_crypt($key, $alg) if $CR;
ok(ref($db), "Database object loaded");
&wrdb($db, "NOTEDB::binary");
}
SKIP: {
eval { require NOTEDB::general; };
skip "Config::General not installed, skipping test for NOTEDB::general", 1 if $@;
unlink "t/general.out";
my $db2 = NOTEDB::general->new(dbname => "t/general.out");
$db2->use_crypt($key, $alg) if $CR;
ok(ref($db2), "Database object loaded");
&wrdb($db2, "NOTEDB::general");
}
SKIP: {
eval { require NOTEDB::text; };
skip "Storable not installed, skipping test for NOTEDB::text", 1 if $@;
unlink "t/test.out";
my $db3 = NOTEDB::text->new(dbname => "t/text.out");
$db3->use_crypt($key, $alg) if $CR;
ok(ref($db3), "Database object loaded");
&wrdb($db3, "NOTEDB::text");
}
SKIP: {
eval { require NOTEDB::dumper; };
skip "Data::Dumper not installed, skipping test for NOTEDB::dumper", 1 if $@;
unlink "t/dumper.out";
my $db4 = NOTEDB::dumper->new(dbname => "t/dumper.out");
$db4->use_crypt($key, $alg) if $CR;
ok(ref($db4), "Database object loaded");
&wrdb($db4, "NOTEDB::dumper");
}
SKIP: {
eval { require NOTEDB::dbm; };
skip "DB_File not installed, skipping test for NOTEDB::dbm", 1 if $@;
unlink "t/note.dbm";
unlink "t/date.dbm";
my $db5 = NOTEDB::dbm->new(dbname => "t");
$db5->use_crypt($key, $alg) if $CR;
ok(ref($db5), "Database object loaded");
&wrdb($db5, "NOTEDB::dbm");
}
}
SKIP: {
eval { require NOTEDB::pwsafe3; };
skip "Crypt::PWSafe3 not installed, skipping test for NOTEDB::pwsafe3", 1 if $@;
unlink "t/pwsafe3.out";
my $db6 = NOTEDB::pwsafe3->new(dbname => "t/pwsafe3.out");
$db6->{key} = "01010101";
ok(ref($db6), "Database object loaded");
&wrdb3($db6, "NOTEDB::pwsafe3");
}
sub wrdb {
my ($db, $name) = @_;
is_deeply($db->{use_cache}, undef, "$name: Chache disabled");
$db->set_new(1, $expect->{1}->{note}, $expect->{1}->{date});
my ($note, $date) = $db->get_single(1);
like($note, qr/any new text/, "$name: Retrieve newly written entry content");
like($date, qr/^\d\d/, "$name: Retrieve newly written entry date");
$db->set_new(2, $expect->{2}->{note}, $expect->{2}->{date});
my $next = $db->get_nextnum();
is_deeply($next, 3, "$name: Get next note id");
my %all = $db->get_all();
is_deeply($expect, \%all, "$name: Get all notes hash") or diag(Dumper(\%all));
}
sub wrdb3 {
my ($db, $name) = @_;
is_deeply($db->{use_cache}, undef, "$name: Chache disabled");
my $ex3 = $expect;
my $n = $db->get_nextnum;
$db->set_new($n, $ex3->{1}->{note}, $ex3->{1}->{date});
$ex3->{$n} = delete $ex3->{1};
my ($note, $date) = $db->get_single($n);
like($note, qr/any new text/, "$name: Retrieve newly written entry content");
like($date, qr/^\d\d/, "$name: Retrieve newly written entry date");
$n = $db->get_nextnum;
$db->set_new($n, $ex3->{2}->{note}, $ex3->{2}->{date});
$ex3->{$n} = delete $ex3->{2};
# hack db file mtime, since we're too fast here
$db->{mtime} = 0;
my %all = $db->get_all();
# hack %all to that it passes the next test
foreach my $n (keys %all) {
chomp $all{$n}->{note};
}
is_deeply($ex3, \%all, "$name: Get all notes hash") or diag(Dumper(\%all));
}