This is code for an agent that will connect to a server, get all the databases (and templates) on the server, and write a ton of information about each database to a comma-delimited file for your spreadsheeting pleasure:
Just import the LSS file into a new agent, save it, and run it. You will be prompted for a server and an output file name, and in return you will get a CSV file with lots and lots of information.
Note that I have only tested this on Domino 8 and you MUST have rights to run remote console commands on the server you run this against -- if you don't, you can get a subset of this information using NotesDbDirectory, but it's a LOT slower (I leave this as an exercise for the reader). Also, the code to get a list of servers is Windows-only, so you Mac guys may need to comment a few things out (not sure).
Oh, and speaking of CSV files, the reverend Steve McDonagh posted a fix to my CsvReader class for those of you who need to use CsvReader on an iSeries box. Apparently you have to open text files in a very special way on an iSeries.
Well, then someone told me that some countries won't accept your passport if it's going to expire within 6 months of your anticipated return date. I thought that was strange, but I did a quick search (since Google knows everything) and sure enough it's true. In fact, you can even look up the country you're going to on the US International Travel site and check the passport expiration rules.
Just to be safe I went ahead and renewed my passport. I even paid the extra $60 for the "Expedited" service since CollabU and UKLUG are next month, and I remember that a few people had serious delays with their passports before ILUG last year. Happily, I got my new passport less than 2 weeks after I sent the application off (along with my current passport, which was a little scary to be without) for processing. It's nice when things work the way they're supposed to.
AskANinja also has the best explanation of the problem with Net Neutrality I've ever heard.
It's not quite as smooth as the Hasselhoffian recursion (thanks Damien) or the Sierpinski zoom, but it's not bad for something I threw together in front of the TV. If you have greater graphic abilities than I do (which is likely), please feel free to improve on the technique.
In a hurry for dinner? Late for work? Don't worry men, just apply a little Manscara and Guy-Liner and you'll be as fresh as ever.
Dude, you look Mantastic!
It's about the size of a small teapot. I thought it was a loofah sponge that the dog dragged into the yard, but it was rooted to the ground. A little Internet research later, and I'm pretty sure it's a Sparassis crispa, also known as a Cauliflower Mushroom. Supposedly it's edible and delicious when young and fresh, but I don't think I'll be eating it.
Just for kicks, I also uploaded the picture to WikiMedia Commons. I'm not a Wikipedia contributor or anything (well, I guess I am now), but I had a hard enough time identifying what the heck it was that I figured I'd share the photo with the world. Maybe that'll help someone else.
For example, here's an agent that will run NBTStat to attempt to determine the machine name and user login name for a given IP address:
import lotus.domino.*; import java.net.*; import java.io.*; import java.util.*; // NOTE: Agent Runtime Security must be at least 2, and // agent signer must be able to run unrestricted operations public class JavaAgent extends AgentBase { public void NotesMain() { try { Session session = getSession(); AgentContext agentContext = session.getAgentContext(); Document doc = agentContext.getDocumentContext(); String remoteAddr = doc.getItemValueString("Remote_Addr"); InetAddress addr = InetAddress.getByName(remoteAddr); PrintWriter pw = getAgentOutput(); pw.println("Remote address is: " + addr.getHostName()); String[] cmd = new String[3]; cmd[0] = "cmd.exe" ; cmd[1] = "/C" ; cmd[2] = "nbtstat -A " + remoteAddr; // must be run with unrestricted access Runtime rt = Runtime.getRuntime(); Process proc = rt.exec(cmd); BufferedReader in = new BufferedReader( new InputStreamReader(proc.getInputStream()) ); BufferedReader err = new BufferedReader( new InputStreamReader(proc.getErrorStream()) ); //int exitVal = proc.waitFor(); // instead of printing the output, you could parse it of course String line = ""; pw.println("<br/><br/><b>Output is:</b><br/>"); while ( (line = in.readLine()) != null) pw.println("<br/>" + line); pw.println("<br/><br/><b>Errors were:</b><br>"); while ( (line = err.readLine()) != null) pw.println("<br/>" + line); } catch(Exception e) { e.printStackTrace(); } } }
As I mention in the code comments, an agent using this technique must have a runtime security setting of at least 2 ("Allow restricted operations"), and the agent signer must have the ability to run unrestricted operations.
Before I get into bullet points though, there was an interesting diversion on one of the pages that came up in my searches. On "The Glass Is Too Big" blog, there was some discussion on using MS SAPI to convert an RSS feed to a podcast, along with some instructions on how to compile JavaScript to an EXE file using the free .NET SDK -- in fact, you may already have the jsc.exe file in your C:\WINDOWS\Microsoft.NET\Framework\v### folder. I'm going to file that away under the "might be interesting to try out sometime" category in my brain. (Yes, I know that technically it's JScript being written/compiled, not JavaScript.)
Anyway, a few tidbits about SAPI:
On the LotusScript side of things, here's a slightly longer bit of sample code than before:
Sub Initialize Dim spVoice As Variant Dim voices As Variant Dim v As Variant Dim i As Integer Dim msg As String Set spVoice = CreateObject("SAPI.SpVoice") Set voices = spVoice.getVoices() For i = 0 To voices.Count-1 Set v = voices.Item(i) Set spVoice.Voice = v msg = "Voice " & i & " is called " & v.GetDescription(0) Print msg Call spVoice.Speak(msg, 0) Next Dim fileStream As Variant Dim fileName As String Set fileStream = CreateObject("SAPI.SpFileStream") fileName = "C:\TestAudioOutputStream.wav" Call fileStream.Open(fileName, 3, False) Set spVoice.AudioOutputStream = fileStream Call spVoice.Speak("I got two. turn tables, and a microphone", 0) Call fileStream.Close Set spVoice.AudioOutputStream = Nothing End Sub
Sub Click(Source As Button) Dim voice As Variant Set voice = CreateObject("SAPI.SpVoice") Call voice.Speak("Would you like to play a game?", 0) End Sub
Then send the e-mail to someone old enough to remember the movie War Games and get them to click the button.
For bonus points, use Tim Tripcony's event binding code to inject this into the PostOpen event of every view and form in a database.
NOTE: I'm not sure what actually installs the voice library (I think it might be MS Office correction: looks like it's on XP by default), so this may not work on your machine. It certainly won't work on a non-Windows machine. Sorry Mac and Linux guys.