Get DAOS ObjectCount and Size with LotusScript

At AdminCamp last week, I talked about how to get the count of all files in the DAOS repository and it’s overall size using some batch programming in Windows and LINUX.

As an alternative I proposed to use the console command “show dir -xml” to return an xml representation of the properties of all applications in the Domino data directory.

I found some code by Julian Robichaux that does the parsing of the XML structure. I’ve stripped out the relevant code snippets and put together a script lib to get the DAOS Object count and the overall size of all DAOS Objects.

The code writes a summary of these values to a database. You can use this data to create nice looking charts and graphs.

Here is the code:

%REM
	Library DAOS.Objects
	Created Sep 27, 2010 by Ulrich Krause/singultus
	Description: Comments for Library
%END REM
Option Public
Option Declare

Class DbInfoHolder
	Public PropertyList List As String
	Private xh As XmlHelper
	Private tNode As NotesDOMNode

	Public Sub New ()
		Set xh = New XmlHelper()
	End Sub

	Public Sub GetDbInfo (node As NotesDOMNode)
		Erase PropertyList
		On Error Resume Next
		PropertyList("Title") = xh.getNodeText(xh.findFirstChildNode(node, "title"))
		Set tNode = xh.findFirstChildNode(node, "daos")
		PropertyList("DAOSEnabled") = xh.getAttributeText(tNode, "enabled")
		PropertyList("DAOSObjects") = xh.getAttributeText(tNode, "objects")
		PropertyList("DAOSBytes") = xh.getAttributeText(tNode, "bytes")
	End Sub

End Class

Class XmlHelper
	Function getNodeText (node As NotesDOMNode) As String
		'** get the text of the given node
		Dim child As NotesDOMNode
		Dim childText As String

		If (node Is Nothing) Then
			Exit Function
		Elseif (node.IsNull) Then
			Exit Function
		End If

		Set child = node.FirstChild
		Do Until (child.IsNull)
			If (child.NodeType = DOMNODETYPE_TEXT_NODE) Then
				childText = childText + child.NodeValue
			Elseif (child.NodeType = DOMNODETYPE_CDATASECTION_NODE) Then
				childText = childText + child.NodeValue
			End If
			Set child = child.NextSibling
		Loop

		getNodeText = childText
	End Function

	Function getAttributeText (node As NotesDOMNode, attrName As String) As String
		'** get the text of a given attribute
		Dim attrList As NotesDOMNamedNodeMap
		Dim attr As NotesDOMNode
		Dim attrValue As String
		Dim i As Integer

		If (node Is Nothing) Then
			Exit Function
		Elseif (node.IsNull) Then
			Exit Function
		End If

		Set attrList = node.Attributes

		For i = 1 To attrList.NumberOfEntries
			Set attr = attrList.GetItem(i)
			If (attr.NodeName = attrName) Then
				attrValue = attr.NodeValue
			End If
		Next

		getAttributeText = attrValue
	End Function

	Function findFirstChildNode (node As NotesDOMNode, childName As String) As NotesDOMNode
		'** get the first child node with the given name
		Set findFirstChildNode = findChildNode(node, childName, 1)
	End Function

	Function findChildNode (node As NotesDOMNode, childName As String, count As Integer) As NotesDOMNode
		'** get the child node with the given name at the given position
		Dim child As NotesDOMNode
		Dim i As Integer

		If (node Is Nothing) Then
			Exit Function
		Elseif (node.IsNull) Then
			Exit Function
		End If

		Set child = node.FirstChild
		Do Until (child.IsNull)
			If (child.NodeName = childName) Then
				i = i + 1
				If (i >= count) Then
					Exit Do
				End If
			End If
			Set child = child.NextSibling
		Loop

		Set findChildNode = child
	End Function

End Class

%REM
NOTE: You MUST have rights to run remote console commands
on the server you want to get a list of files from.

Parts of the code by Julian Robichaux
http://www.nsftools.com,14 Aug 2008
%END REM

Class DAOSObjects

	Public Sub New ()

	End Sub

	Public Sub ObjectCount

		Dim s As New NotesSession
		Dim db As NotesDatabase
		Dim doc As NotesDocument
		Set db = s.CurrentDatabase

		Dim session As New NotesSession
		Dim commandString As String
		Dim server As String
		Dim returnString As String
		Dim dbInfo As New DbInfoHolder
		server = session.UserName
		commandString = "!show dir -xml"
		returnString = s.SendConsoleCommand(server,commandstring)

		'** if we got some output, try to process it as XML
		Dim xHelper As New XmlHelper()
		Dim inputStream As NotesStream
		Dim outputStream As NotesStream
		Dim domParser As NotesDOMParser
		Dim docNode As NotesDOMDocumentNode
		Dim fileNode As NotesDOMNode
		Dim dbNode As NotesDOMNode

		'** load it up into a DOM parser
		Set inputStream = session.CreateStream
		Call inputStream.WriteText(returnString)
		inputStream.Position = 0
		Set outputStream = session.CreateStream
		Set domParser=session.CreateDOMParser(inputStream, outputStream)
		domParser.Process

		'** all of the tasks should be contained within a single
		'** node, as separate  entries.
		Set docNode = domParser.Document

		'** find the  node
		Set fileNode = xHelper.findFirstChildNode(docNode, "files")

		'** if we didn't find anything, exit
		If (fileNode.IsNull) Then
			Exit Sub
		End If

		Dim sumObj As Currency
		Dim sumSize As Currency
		sumObj = 0
		sumSize = 0

		Set dbNode = fileNode.FirstChild

		Do Until (dbNode.IsNull)
			If (dbNode.NodeType = DOMNODETYPE_ELEMENT_NODE) And _
			(dbNode.NodeName = "filedata") Then
				Call dbInfo.GetDbInfo(dbNode)
				If dbInfo.PropertyList("DAOSEnabled")= "readwrite" Then
					sumObj = sumObj + Ccur(dbInfo.PropertyList("DAOSObjects"))
					sumSize = sumSize + Ccur(dbInfo.PropertyList("DAOSBytes"))
				End If
			End If
			Set dbNode = dbNode.NextSibling
		Loop

		Set doc = db.CreateDocument
		doc.form = "DAOS.Objects"
		doc.servername = server
		doc.sumObjects = Cstr(sumObj)
		doc.sumSize = Cstr(sumSize)
		Call doc.save (False, False )
	End Sub

End Class

You can download the code as .lss file here.


AdminCamp 2010, Gelsenkirchen – Warmup

In a few hours, I will drive to Gelsenkirchen for this years AdminCamp. Traditionally sunday is the day for speakers and those attendees who show up at this day. There will be a #lotusbeer in the hotel in the evening.

As I posted earlier in this blog, I have two sessions this year. In addition I will speak at the Closing General Session together with my fellows Tim Pistor and Werner Motzet. We were asked only a few days ago to do the CGS and so we have to prepare a few things.

In general the CGS will be about “Lotus Notes Community – we have a solution for everything” . Not sure which topics we will cover in particular, but Tim’s webservice to make Lotus Notes brew a fresh and tasty cup of coffee will be part of the show.

Here is a slide that shows a few representatives of the Lotus Notes / Domino community.

Don’t flame us, if you do not find yourself on the slide. It is only a selection of some members of a much bigger community. We are aware of this.


Upcoming book reviews: IBM Lotus Notes 8.5 User Guide and IBM Lotus Sametime 8 Essentials : A User’s Giude

Again I was asked by Packt Publishing to review a couple of new books. Despite the fact that I am an administrator and developer, I agreed. It’s worth to have a look at the dark side of our business, … users :-).

I will review the Karen Hoopers brand new “IBM Lotus Notes 8.5 User Guide” and also “IBM Lotus Sametime 8 Essentials : A User’s Giude” written by Marie L. Scott and Thomas Duff.

The first book has already been released in August and the second one is about to be published in September 2010. Pre-order now and save 43%.

Packt Publishing has recently launched PacktLib. This service, Packtlib, will enable readers to subscribe to an entire catalogue of books to supplement the Packt print books they already possess.

Readers can access and search across Packt’s entire library of over 400 books, finding practical solutions to your everyday IT problems.


Is it possible to edit the reply prefix “RE:” in iNotes for different languages?

Yes, it is possible to change the reply prefix in iNotes for all languages, along with other strings that may need to be changed for customisation purposes. These strings are stored as variables in the dwa_XX.properties file in the Forms85.nsf design under Resources -> Files (XX in this case is the two character representation of the language in use).

For example in the German properties file dwa_de.properties, to change the reply prefix from “Antwort: ” to “RE: ” the following variable should be changed from:

L_RE=Antwort:

to

L_RE=RE:

Then after the cache is cleared (or server is restarted) the changes will be noticeable in the iNotes interface.

Source: Lotus Software KnowledgeBase #1443220