Novell Home

HowTo: Create a simple Document Management Application Part 2

Novell Cool Solutions: Feature
By Stomfi

Digg This - Slashdot This

Posted: 28 Jul 2005
 

StomfiLearning to use Linux at Home and Work
Welcome to my ongoing series of HowTo articles designed to help Linux newbies get comfortable with Linux. Before trying any of these HowTos, take a few minutes to study the prerequisites so you can hit the ground running.
--Stomfi

This HowTo shows you how to create a simple Document Management System using the Shell and Runtime Revolution.

I have used some new shell tools, and some new RunRev functions in this project, so that you can increase your knowledge.

Special Offer for Cool Solutions Readers: Free Copy of Runtime Revolution
The good folks at Runtime Revolution have extended a special offer to Cool Solutions readers to make it easier for you to implement the great ideas in Stomfi's articles. They are offering it for free to Novell customers who know the secret code. See this page for details.

The new shell tools are some of the bibliographic database tools, namely "indxbib" and "lkbib". These are part of the "refer" suite. Refer was designed to add troff/nroff/groff formatted references to a document. We shall be using them for our own purposes, using a subset of the possible database entries. You can look up the manual pages for "refer" to see all the possible entries. The reason we are using these tools is that they are suitable, and who wants to waste time reinventing them.

I've used a new RunRev function in this project for making and selecting items from a menu, and I've used one of the windows for two activities, both adding and editing, by changing the property of the display field, and adding a flag to tell which mode we are using. I've also set up a new construct that passes a flag to the program about which calling screen to return to. This is really simple RunRev scripting as I do all the information processing with the Linux shell tools, which were designed for that purpose.

The RunRev windows and the first of the scripts were developed in Part one of this HowTo.

This is a picture of the ADDDOC window where you can add details for a new document or edit those of an existing one.

This picture shows that the Title of the record for the `SCOOL document details has been changed.

These are the rest of the scripts that allow this application to perform its activities:

ADDDOC card script

on openCard

   global TITL

   global AUTH

   global NDATE

   global PUBL

   global PUBLC

   global EZINE

   global EZINES

   global DBFILE

   global EDITME

   if EDITME <> empty

   then

      set the listBehavior of field "DOCUMENT" to false

      put ($HOME & "/docmanage/bin/looked.sh" && quote & EDITME & quote) into ERECORD

      replace return with empty in ERECORD

      put the shell of ERECORD into EDOC

      #put EDOC into field "DEBUG"

      put line 7 of EDOC into TITL

      put line 1 of EDOC into AUTH

      put line 4 of EDOC into NDATE

      put line 2 of EDOC into PUBL

      put line 3 of EDOC into PUBLC

      put line 6 of EDOC into EZINE

      put line 5 of EDOC into EZINES

      put line 9 of EDOC into DBFILE

      put line 4 of EDOC & return into field "DOCUMENT"

      put line 1 of EDOC & return after field "DOCUMENT"

      put line 7 of EDOC & return after field "DOCUMENT"

      put line 2 of EDOC & return after field "DOCUMENT"

      put line 3 of EDOC & return after field "DOCUMENT"

      put line 6 of EDOC & return after field "DOCUMENT"

      put line 5 of EDOC & return after field "DOCUMENT"

      put line 9 of EDOC into field "BIBFILE"

   else

      put empty into TITL

      put empty into AUTH

      put empty into NDATE

      put empty into PUBL

      put empty into PUBLC

      put empty into EZINE

      put empty into EZINES

      put empty into field "BIBFILE"

      put empty into field "DOCUMENT"

      put ("First Choose File from this list or" & return & "click empty line for New Database") into field "DOCUMENT"

      put (return & "***********************" & return) after field "DOCUMENT"

      put ( $HOME & "/docmanage/dict/papers") into DOCDBDIR

      put ("ls" && DOCDBDIR & "| grep -v" && quote & "\.i" & quote ) into FLIST

      replace return with empty in FLIST

      put the shell of FLIST after field "DOCUMENT"

      set the listBehavior of field "DOCUMENT" to true
   
   end if

end openCard

This is our double purpose window. The if condition looks at EDITME and if it finds something in there, sets the list behaviour and uses it to find the record using the following shell script.

#!/bin/bash

#

#looked.sh SearchTerms

#Returns fields for editing function

#Set Database Folder

DBFLDR="$HOME/docmanage/dict/papers/"

#Change folder to make command line less wordy

cd $DBFLDR

#Make a list of Databases

DBLIST=`ls | grep -v "\.i"`

#

#Strip the leading Title: string from $1

LKEY=`echo $1 | cut -d":" -f2-`

#

#Create command line DB option list

DBOPTIONS=""

BIBDBF=""

for DBF in $DBLIST

do

   #First make sure that the indexes are up to date

   indxbib $DBF

   #Construct the options part of the line

   DBOPTIONS="$DBOPTIONS -p $DBF"

   #Find out if this is the BIBDBF file

   if [ "${#BIBDBF}" -lt 1 ]

   then

      BIBDBF=`grep -iF "$LKEY" $DBF`

      if [ "${#BIBDBF}" -gt 1 ]

      then

         DBFILE=$DBF

      fi

   fi

done

#

#list matching record

lkbib $DBOPTIONS "$LKEY" |\

sed -f $HOME/docmanage/bin/noheadings.sed > $HOME/docmanage/erec.txt

#echo the BIBDBF file

echo $DBFILE >> $HOME/docmanage/erec.txt

cat $HOME/docmanage/erec.txt 

Much of this script is similar to the lookup.sh script. We find out which database file contains the Title string and use that for the lkbib option. We list the record, use the sed script noheadings.sed to strip off the % references and send the result to a temporary file. We echo the database name to the end of that file and send the result back to RunRev. This is the sed file.

s/%A//

s/%B//

s/%C//

s/%D//

s/%K//

s/%S//

s/%T//

You can see it substitutes the first pattern with nothing.

The else statement for the ADDDOC card script is for adding a new record when the ADD menu is clicked from the START button. It sets all the name holders to empty, puts a message into the DOCUMENT display field, calls a shell function to put the names of the existing databases after the message, and sets the list behaviour to "true" so you can click in it to perform the required action.

DOCUMENT field script.

on mouseDown

   global DBFILE

   put the selectedText of me into DBFILE

   if DBFILE <> empty

   then

      put DBFILE into field "BIBFILE"

   else

      ask "Please Enter a New or Old File Name to save your record"

      put it into DBFILE

      put DBFILE into field "BIBFILE"

   end if

   put empty into field "DOCUMENT"

   set the listBehavior of field "DOCUMENT" to false

end mouseDown

This script only works when the list behaviour is set to "true" helping the ADDDOC window perform its double function.

Year button

on mouseUp

   ask "Year"

   global NDATE

   put it into NDATE

   put "DATE:" && NDATE into line 1 of field "DOCUMENT"

end mouseUp

All the document details buttons have similar scripts. You can work out the name holders from the next script and the line number to put it into from the order of the buttons on the window.

EXIT button script

on mouseUp

   global TITL

   global AUTH

   global NDATE

   global PUBL

   global PUBLC

   global EZINE

   global EZINES

   global DBFILE

   global EDITME

   put ($HOME & "/docmanage/dict/papers/" & DBFILE) into BIBDBFILE

   replace return with empty in BIBDBFILE

   if TITL <> empty and AUTH <> empty and NDATE <> empty

   then

      put(quote & NDATE & "#" & TITL & "#" & AUTH & "#" & PUBL & "#" & PUBLC & "#" & EZINE & "#" & EZINES & quote) into NEWBIB

      if EDITME <> empty

      then

         put ($HOME & "/docmanage/bin/editbib.sh" && BIBDBFILE && NEWBIB) into DUREC

      else

         put ($HOME & "/docmanage/bin/writebib.sh" && BIBDBFILE && NEWBIB) into DUREC

      end if

      replace return with empty in DUREC

      put the shell of DUREC into DUNREC

   end if

   put empty into EDITME

   global WITCH

   put the name of this card into CNAME

   if CNAME contains WITCH

   then

      put "DocManage" into WITCH

   end if

   go card WITCH

end mouseUp

This script first creates the database path name. It checks to see if enough fields to create a record are filled. If there is, it creates a pattern containing all the field names separated by the # symbol. It checks to see if this is an edit of an existing record or a new record, and sets the relevant shell script. It clears the edit flag, and calls the shell script. Lastly, whether it edited, created or did nothing - it returns to the calling window.

These are the two shell scripts:

#!/bin/bash

#

#editbib.sh BIB Record

#Add records to specified BIBDB

BIBDB="$1"

#These are the record entries in $2

#PDATE=%D $1 AUTH=%A $2 TITL=%T $3 PUBL=%B $4 PUBLC=%C $5 EZINE=%S $6 ESECT=%K $7

#

#Create BIB entry using sed to get rid of the initial space. The back slash escapes the literal meaning of the space.

echo "$2" |\

awk -F"#" '{print "\n","%A "$2"\n","%B "$4"\n","%C "$5"\n","%D "$1"\n","%K "$7"\n","%S "$6"\n","%T "$3"\n","\n"}'|\

sed -e s/^\ // > $HOME/docmanage/newent.txt

#

#Find out which record number contains %T $3

TITL=`echo $2 | cut -d"#" -f3`

RKEY="%T $TITL"

NUMR=`awk -v KEYR="$RKEY" 'BEGIN{RS = ""};{if($0 ~ KEYR) print NR }' $BIBDB`

#

#remove temporary file

rm -f $HOME/docmanage/newfile.txt

#

#Use the awk getline function to replace the record

awk -v NEWREC="$HOME/docmanage/newent.txt" -v RNUM=$NUMR '\

BEGIN{RS = "";ORS = "\n\n";OFS= "\n"};\

{if(NR != RNUM) {print $0}\

else {getline < NEWREC; print $0}}' $BIBDB > $HOME/docmanage/newfile.txt

#

#If success replace original database

if [ ! -z $HOME/docmanage/newfile.txt ]

then

   rm -f $BIBDB

   mv $HOME/docmanage/newfile.txt $BIBDB

   echo "DUN"

   #Update BIB index

   indxbib $BIBDB

fi

The editbib.sh script uses the awk getline function to replace the record equal to the record number of the identified record, printing out all other lines. We have used the get line function before in the Home Cookbook articles, so you should be familiar with its use. To make sure that the look up functions work in other parts of the application, the "indxbib" shell tool is used after any changes or additions to the database.

#!/bin/bash

#

#addbib.sh BIB Record

#Add records to specified BIBDB

BIBDB="$1"

#Create BIBDB if not exist

if [ ! -e "$BIBDB" ]

   then

touch $BIBDB

fi

#These are the record entries in $2

#PDATE=%D $1 AUTH=%A $2 TITL=%T $3 PUBL=%B $4 PUBLC=%C $5 EZINE=%S $6 ESECT=%K $7

#

#Create BIB entry

echo "$2" |\

awk -F"#" '{print " \n","%A "$2"\n","%B "$4"\n","%C "$5"\n","%D "$1"\n","%K "$7"\n","%S "$6"\n","%T "$3"\n"}' >> "$1"

echo "DUN"

#Update BIB index

indxbib $BIBDB

This script is pretty straight forward as its function craete a new database if it doesn't exist and to write a new record on the end of the database file, making sure that there is at least one newline separating each record. This is done by the "\n" at each end of the awk print function.

Card Help Button exit

on mouseUp

   global WITCH

   put the name of this card into CNAME

   if CNAME contains WITCH

   then

      put "DocManage" into WITCH

   end if

   go card WITCH

end mouseUp

This is the help button exit script. I haven't been window specific with the help, but if you want to do this then you can create a text file for each window, copy this same button to any that are missing it, and change the HELP button script adding these extra lines to each window. This example is for the START window.

on mouseUp

   global WITCH

   put "DocManage" into WITCH

   #Extra lines for specific window help

   put ($HOME &"/docmanage/starthelp.txt") into HELPDOC

   put empty into field "HELPTXT" of card "HELP"

   put HELPDOC into field "HELPTXT" of card "HELP"

   #End of extra lines

   go card "HELP"

end mouseUp

You can copy this script from the "DocManage" card, paste it into all the other Help button scripts, and change "starthelp.txt" to the name of the relevant help file for that window, and change "DocManage" into the name of the card the HELP button is on. Or you can copy and past just the extra lines changing the name of the help file.

This is the end of this series. It is nice and simple allowing you to add extra features. You can use the other fields described in the refer manual page for what ever extra details you want. For example, you could add a page reference for magazine or journal articles, or you could add a web page URL for web articles, or products and services your business may be interested in, adding extra buttons on the ADDDOC window, and modifying the scripts accordingly.

You can separate your records into many databases, and if you want to store them in a logical place in your file system, put symbolic links to them into the $HOME/docmanage/dict/papers folder.

In a networked environment, you could distribute the Stand Alone to other people and set the database links folder in the application to a readable folder on the server. This way you can access similar databases with different detail fields across a network. Your network administrator may have to set the links up for you and your fellow workers.

There are plenty of professional tools that do similar things, but this works, you made it yourself, you or anyone with basic Linux skills can modify it to suit specific needs, it's not bloated with features you will never need, and it didn't cost any money. What could be better than all of that. Go Linux Newbie!


Novell Cool Solutions (corporate web communities) are produced by WebWise Solutions. www.webwiseone.com

© 2014 Novell