Ready For Use

Wed Feb 23 11:18:41 EST 2011

Tags: gcd

Well, Project One is down: I set up a first draft of my new Getting Crap Done database. I did indeed set it up on Domino, so I didn't have to worry about user authentication, and that helped quite a bit. It's very quick and dirty, using some basic controls and a certain old style I had sitting around:

Getting Things Done: Items

It really does just what I need: keeps tracks of item names, the date or range (now, short, medium, long), and allows for repeating items, plug a big ol' rich text field for generic notes:

Getting Crap Done: Item

Since it's Domino, multi-user functions were a cinch and it was easy to add in some items for making items available for viewing or editing by others, and those fields also handled showing only your items with no chance of stumbling across anyone else's illicitly.

I also added a feed to my home page to keep it in my face at all times. In later phases, I'll add in stuff like RSS feeds and email reminders. More importantly, though, this should help me hold my own feet to the fire on on the other things I need to get done.

Getting Crap Done

Tue Feb 22 10:21:23 EST 2011

Tags: gcd

So I think my first project should be a quick little app to keep track of the things I need to do. This is well-trodden ground and I could easily just pick up a free app to do it, but it should provide a good exercise, and I'll get to do it like I want.

Basically, the way I want to do it is pretty similar to the project-tracking database I wrote for work, or at least the sidebar view I made for it. The basic UI is just a list of things to do with short summaries, categorized by their due date, and icon- and color-coded for status and rushness. In a non-work setting,Ā The former could translate to vague timeframes of "now", "soon", "long-term", etc. and the latter could translate to "importance". I'll also have to work in some support for recurring events, like "pay the non-automatic bills." I don't think I'd need all the categorization I have at work - my personal projects are much looser than the client-driven work ones, so maybe just a tag or two would do the job.

Really, the goal is to just get a list of things that I have to do in my face at all times (or, at least, in a place I will actually check regularly, so maybe I'll have it send me email). I've historically had a nasty tendency to let things drift out of mind, but I'm putting an end to it, and I'll make this app reflect that. I'll use my natural aversion to red "past due" text to keep me going.

I'll have to pick a medium. My default lately is XPages, which is my work development environment, but I'm always itching to try something else. Nonetheless, XPages may win out - if nothing else, I don't want to bother writing a user authentication and DB access system or any of the other "structural" elements that would stand in between me and getting it started. The whole point is to make sure I actually get crap done, after all, not spin my wheels with abandoned drafts.

Gaze Upon My Works

Mon Feb 21 21:26:21 EST 2011

Tags: projects

So I think I need a project to work on.

Back during my education, when I had weeks of time on my hands, I had projects going all the time, the mostĀ prominentĀ of which was my old blogging site. Aside from that, though, I had lots of little things - server admin stuff like setting up mail access, getting Gaim to work on OS X back when that meant using the non-Apple XFree86 build, and my on-again-off-again relationship with building pseudo-filesystems with MySQL in Java, Objective-C, or Ruby.

Then, I started working and actually doing Ā things with my time, and my beloved projects have gone by the wayside. For a while, even when I had free time, I'd be too tired and annoyed from work to do much other than play WoW or watch TV. I've still finished a couple small-time projects here and there, like my new home page when I finally got fed up with my ancient My Yahoo home page, my AIM log parser DB, and a little runeword-tracking app for Diablo II. My big project lately, which has been taking longer than it realistically should have, has been the new forums/raid comp utility for my guild. That's finally just about good to go, which means my spare programming time will be free.

So: what's next? A couple candidates come to mine:

  • Another blogging platform. I've already done this, but I'd love to take a whack at it in Ruby or another modern language, not PHP. I have to admit, though, that (NIH flareups aside) WordPress is doing a fine job.
  • Some just-for-fun apps in Cocoa. I have only a cursory knowledge of Cocoa, and it'd serve me very well to learn how to write Mac and iOS apps.
  • Some stuff in Cappuccino. This would have much the same effect as learning Cocoa, but would keep within my usual web-dev domain (which could be either a plus or a minus).
  • More Minecraft Server work. This could be fun, but I'm getting pretty tired of looking at Java all day.
  • Plugins for Plex. I've recently switched to using my Mac mini in lieu of a proper cable TV subscription, but there are some rough edges. Namely, Plex's YouTube app is pretty feature-light, but XBMC doesn't support Hulu or Netflix. Plex plugins are just Python, though, which is like Ruby if you squint, so maybe I could fix it myself.
  • More WoW stuff. I'm not sure what specifically I'd do next, but there are plenty of places I can improve the forums and raid comp tool.

The important thing, though, is that, now that I've written it down in a public forum, I'll have to do something. All I have to do is decide what, and the rest is an implementation detail.

Running Minecraft as a Domino Server Task

Thu Jan 13 13:57:51 EST 2011

Tags: projects

A couple months back, I started getting into the wonderful game Minecraft, which I heartily recommend. Since I really just wanted to play the multiplayer one, I decided to try setting up my own server. The actual setup is very easy - drop the minecraft_server.jar file from their download page somewhere on your computer and launch it. The tough part was making sure it'd do real server stuff like, primarily, launching automatically at startup.

I looked around a bit for ways to create normal Windows services ro run a Java app, but the process I found looked painful. Then, I realized that I already HAVE a server capable of running Java-based tasks with aplomb - Domino. After not a lot of searching, I found the perfect starting point: http://nsftools.com/tips/JavaAddinTest.java.

Now, I had a couple choices for how I could implement this: I could extract the JAR and figure out how to run the server from the raw classes, essentially writing my own server; I could include the JAR in my project and run the main(...) method of the server class; or I could go the "easy" route and just run the Java task externally. Though the first two would be interesting and are potentially something I'll look into down the line, I went with the final option and it's been serving me pretty well.

Basically, the Java task, when loaded, does a system call to run java.exe to load the server and attaches a couple stream readers to that to read in the standard and error output from the task (error-out from Minecraft appears to include tons of non-error information).

That was sufficient to get it up and running, but I decided to be a little tricker. I set up a database to house reports and config parameters (yes, yes, I know you're not supposed to put database file paths in code, but meh). That way, I can keep a log of all the messages in a searchable format, keep track of the users that have logged in and their last login times, and store parameters like the memory sizes and Java and JAR paths without having to re-edit the server task code for every change.

It's been working out pretty well! I've been working on an XPages UI along side it for viewing the information and sending along server messages, and I'll eventually put in an editor for the .properties file the server uses for its startup preferences.

Here's the (likely bug-ridden) code I'm using:

MinecraftServer.java

Now THERE's a terrific idea

Tue Dec 21 09:53:54 EST 2010

Tags: projects

This post over at Codestore hit me as one of those "oh huh... why aren't I doing that?" things. My current computer setup is blessedly homogenous, consisting of a handful of Macs. Since pretty much everything on the Mac, including Chrome, stores saved passwords in the Keychain, which is then synced across my computers via iTools .Mac MobileMe, I don't even need to use 1Password to assist me (though I have a license around somewhere). Keychain Access has a nice random-password generator when you go to change the Keychain password, and I've also found the results of @HashPassword(@Unique) in Formula language to be quite suitable.

Learning the "Right" Way to Write XPages

Sun Nov 28 13:52:27 EST 2010

Tags: xpages

XPages are a tough nut to crack. Thanks to IBM's apparent disinterest in people using their software (which is a big topic in itself), it's an uphill battle to figure out what to do with them. For simple applications, they're overkill - loading a Java framework stack that seems to go on for miles has some noticeable performance penalties. But for larger applications, how are you supposed to write them? The main tutorials I've run across usually involve replicating basic form/view functionality or porting an example Notes application over. That's great, but I already know how to make apps with forms and views.

A couple sources, such as the excellent Mindoo blog and the well-produced Notes in 9 give hints at the "other" way to do XPages development, the way involving pure Java classes and scoped beans. From what I've gathered in my development, this is the "Right" way to do it, but, unfortunately, those blog posts and videos are about the extent of what I've found. I imagine that I could learn more if I hired consultants or attended LUGs in various parts of the world, but those seem like pretty ridiculous solutions to the problem.

Since XPages are an application of JSF, I could run off in that direction, but there are severe problems with that plan, not the least of which is that the XPage tag library is very distinct from other JSF applications and so reading any of those books would beĀ analogousĀ to learning MFC by reading a book about Qt. Same language and same general concepts, sure, but it's not the same environment.

This ambiguity manifests in practical problems. I'm writing a forum at the moment, and I'm wondering what the best way to do it is. On a topic page, for example, I have a topic ID and I want to display a paginated view of the posts in that topic. The straightforward and functional way to do it is to use a <xp:dominoView/> data source with a categoryFilter and feed that to a <xp:repeat/> control. That works and initially is pretty clean - showing data from a view is easy. But then I want to show the author's preferred alias instead of their username, so I put in a custom control with code to look that up. Oh, and some code to determine and show the author's current avatar image. And some code to determine if the current user can edit or delete the post. And some code to look for previous versions of the post to show an edit history. And some code to add or remove the topic from the list of the user's favorite topics. And so on and so on.

None of that code is particularly crazy, and I've moved a lot of it into custom controls to keep it nice and clean, but, at this point, I've got all kinds of business logic performing actions and converting <xp:dominoView>s and <xp:dominoDocument/>s into topic lists and posts. The actual XPage itself is supposed to be the View part of a MVC setup, right? Instead, now I have this View/Controller hybrid with a dash of Model when I have to make a secondary data source to get the rich text of the post. That can't be right. Instead, I should probably write some Java classes called Topic, Post, and Author and get all that crap out of the XPage.

And therein lies the problem. I started clean with a fancy new framework, but I've been largely left to my own devices when it comes to figuring out how to use it. Plus, I've not even totally convinced that Java-ifying everything is actually the right way. Once I step away from the pre-provided Data Sources, I'm suddenly on the hook for handling efficient pagination and cacheing myself, plus "smaller" things like getting the rich text data out of the documents and to the web browser. Should I try to read the MIME entity in Java? Should I punt and provide a .getDocument() method on the Post to let the <xp:dominoDocument/> source do the work? It's not clear. Should I read in all of the pertinent data from the document as soon as I instantiate a Post, or should I leave the Document object sitting around and only pull it in on-demand? I guess I'll have to try both and find out if one is much slower.

Eventually, I expect to find a smooth way of accomplishing everything I want to do and all this will be like second nature. But that "eventually" is quite a while, and a far cry from more opinionated software like Rails (which is written in a better language, to boot). Maybe Mastering XPages will help, but it seems I'll have to content myself with muddling through until at least the end of January.

It's Still Lotus Notes

Fri Sep 17 19:35:23 EDT 2010

Tags: notes

XPages are a huge divergence from classic Notes development. Aside from a few token UI controls such as View Panels and some support for Domino data on the back end, they may as well be completely unrelated to Notes.

Now, while IBM didn't take many strides to make the transition from old-style to new-style development easy, they DID make sure to keep the most important part of the Notes experience intact: horrifyingly frustrating bugs! Case in point:

All I wanted to do was delete the attribute value, but every time I did, the XML editor decided to eat a couple extra lines of code. The "select all" effect you see is from hitting ctrl-Z, which is supposed to only select the text that was un-deleted, but, since the editor has no idea what's going on, it throws up its hands and selects all kinds of crap.

Between this kind of thing and all the random crashes, it's comforting to know it's still the same level of Lotus quality we've come to expect.

Turns out Partial Execute is handy

Sun Aug 22 22:53:00 EDT 2010

My main "spare time" project involves working on a lineup editor for raids in WoW. Basically, each player can have one or more characters, each of which can perform one or two roles (out of "Tank", "Healer", or "DPS"), and the UI should allow the person setting it up to pick which character that player will bring and which role they will perform. The setup is a table, with each row looking like:

The checkbox indicates whether or not the player is going on the run, then there's the player name, the currently-selected character (the icon denotes the character's current specialization), then how they originally signed up and their desired role, then three checkboxes for the role, and then their skill/gear rank.

Originally, I had the lineup set up as a Server-Side JavaScript array with ad-hoc objects with fields for each column. This worked out alright at first, but not only stepped all over MVC separation, since the controls had to "know" about the nature of the data they were working with, but made the necessary event-handler code really tangled.

What clinched the deal was the side effects of switching a character or role - not every character can fill every role, so switching a character or role could easily switch the other. Case in point - if I switch my lineup line there to my hunter Elegabal, the role has to change as well:

With a JavaScript array and event handlers, every change meant code attached to the control itself that looked up the current character in the database, the roles they can fill, if they're eligible for the selected role, then either what roles they CAN fill (if a character was picked) or what character is available to fill the selected role. Not impossible, but VERY hairy.

So I switched over to Java objects on the back-end. While the Java code itself is less expressive than JavaScript, the organization is significantly cleaner and more logical. The Lineup is a class that descends from Vector to provide the overall table, and each element is a LineupLine object with getters and setters for each important element. That way, rather than each role radio button having to have code to sanity-check the character, they're just bound to "#{line.role}" and the LineupLine.setRole(String) method handles all the particulars.

Early on, though, I started running into some oddities - I'd pick a different role, the table would refresh, and then my role selection would go back to its previous state. I added in some System.out.print() lines in the Java objects to make sure setRole() was being called and, sure enough, it was - I could see that it was called with the right new value, yet it kept switching back to the old one. Upon further investigation, I found the problem: while the new role was being set, the server was also getting a setCharacter() call with the existing character value. So the role would be switched, then the character would be set, and, since that character couldn't do the new role, it'd naturally switch the character back.

The solution I found was to enable Partial Execution on the input controls. I can only assume that this means that, rather than sending the server the entire contents of the row as the new data to process, it sends only the control's (i.e. the drop-down's or the radio button's) data, which limits the method calls to only the one that actually changed. Presumably, this has the side effect of being slightly faster, since less data is sent to the server to be processed.

Notes 8.5.1's new LotusScript Editor

Thu Oct 15 23:22:43 EDT 2009

Tags: notes

So Notes 8.5.1 is out, and it's not bad as far as Notes clients go. My show-stopping bug is fixed, there's a slew of nifty user features, and, most importantly, they're taking concrete steps to improve the process of actually writing code for their platform.

As I'm sure you know if you've programmed in Notes, the LotusScript editor can be charitably described as "beta quality" and had, from all appearances, not been touched in any way since the addition of LotusScript in R4. Rather than list all of its horrible qualities, I'll try to leave it at this: the editor, from time to time, easts code. As far as I'm concerned, there's nothing worse that a code editor (or any editor, really) can do than destroy code, yet I can't tell you how many times Designer deleted an "End Sub" statement when trying to highlight an error somewhere in the body of the code, creating a nightmarish cascade of syntax errors and automatic code rearrangement. It's really bad.

So the addition of a proper editor for LotusScript (for agents and script libraries, at least) is HUGE; if I had had my choice about what made it into 8.5.0, I'd have picked this over XPages any day. Just the customization is a huge boost. For reference, here's the programming environment I use when I'm enjoying life:

TextMate

And here's the old LotusScript editor:

Old Editor

Right. You can change it around a bit, picking your font (but not font style) and the text color (but not background color), but that's about it. This isn't even showing any of the behavioral problems like the handling of class definitions, the many bugs, or the paucity of useful features found in other editors like mass-indenting, code templates, and the like.

Now that it's a proper Eclipse editor, I can change it around more to my liking (we'll see if I stick with it exactly like this, but it shows the options):

Eclipse Editor

Just as the previous screenshot doesn't convey the bugs, this one doesn't convey the overall feel of the editor. For lack of a better description, I'll say that it now feels like the text editor was designed with the expectation that a programmer might actually use it. I'm sure it'll have its own share of irritants (like having to manually delete the stub parameters when accepting a method auto-completion), but it's already made my job significantly less of a hassle.

Playing sound in the Lotus Notes client

Thu Oct 15 22:47:17 EDT 2009

Tags: notes

From time to time, mostly for fun, I've wanted to figure out how to play arbitrary sound clips in the Notes client. From what I can tell, the "proper" way to do that is to use NotesUIWorkspace.PlayTune(), which, as with so many aspects of Notes, falls far short of what I want. I don't want to do any filesystem or network access (both because that's ugly and also because it should be cross-platform and not depend on being in the office), and so that just won't work.

A while ago, I came up with a method that kind of worked, using Java's "sun.audio.AudioPlayer" class and feeding it data pulled from an HTTP connection. However, this had a couple problems - the audio player returns control as soon as it starts, resulting in the code ending and closing the stream, so I had to either cache the data first or add in a loop to wait for it to finish. More problematically, though, it caused weird problems with the web server wherein the connections didn't properly close, bogging it down to unresponsiveness over time. So... scratch that idea.

Eventually, I came up with something that worked: access the sound files as NotesDocuments (I do it as file resources showing up in a $FormulaClass-modified view, but it should work as attachments to normal documents too), export the docs as DXL, pull out the Base64-encoded sound file data, translate that back, and feed it to the audio player.

I ran into some trouble instantiating some of the objects in a pure-LotusScript implementation, so the library is broken up into two parts: a LotusScript script library with a function that pulls an audio file from the storage DB by name and calls a Java method, and a Java library to do the dirty work of playing the audio. The LotusScript, cleaned slightly, is:

Uselsx "*javacon"
Use "Java Audio"
	
Sub PlayByName(fileName As String)
	Dim jsession As New JavaSession, session As New NotesSession
	Dim storagedb As New NotesDatabase(session.CurrentDatabase.Server, "storagedb.nsf")
		
	If Not storagedb.IsOpen Then Exit Sub
		
	Dim soundEffects As NotesView, effect As NotesDocument
	Set soundEffects = storagedb.GetView("Sound Effects")
	soundEffects.AutoUpdate = False
	Set effect = soundEffects.GetDocumentByKey(fileName, True)
		
	If Not (effect Is Nothing) Then
		Dim exporter As NotesDXLExporter, dxl As String, fileData As String
		Set exporter = session.CreateDXLExporter
		dxl = exporter.Export(effect)
		fileData = Strleftback(Strright(dxl, {<filedata>
}), {
</filedata>})
		Dim audioPlayer As JAVACLASS
		Set audioPlayer = jsession.GetClass("JAudioPlayer")
		Call audioPlayer.play(fileData)
	End If
End Sub

The Java code isn't much worse:

public class JAudioPlayer {
	public static String play(String base64data) {
		AudioStream audioStream;
		try {
			byte[] audioBuffer = new BASE64Decoder().decodeBuffer(base64data);
			ByteArrayInputStream inputStream = new ByteArrayInputStream(audioBuffer);
			
			audioStream = new AudioStream(inputStream);
			AudioPlayer.player.start(audioStream);
		} catch(Exception e) {
			String stackTrace = "";
			for(StackTraceElement element : e.getStackTrace()) {
				stackTrace += element.toString() + "\n";
			}
			return stackTrace;
		}
		return "Success";
	}
	
	public static void stop(AudioStream audioStream) {
		try {
			AudioPlayer.player.stop(audioStream);
		} catch(Exception e) { }
	}
}

Naturally, there's other stuff to worry about, like making the DB, setting up the way you want it stored (if you use normal documents with file attachments, the DXL-searching bit would have to be slightly different), etc., but this is the meat of it.

All in all, this has been working out pretty well. It's not perfect (exporting as DXL would have a lot of waiting time if the audio file is big or the network slow), but it works in Windows and OS X, hasn't caused any server troubles (always a plus), and, since the audio player returns control immediately, the UI doesn't lock up while the file is playing.