Thursday, 26 November 2009

Lift: Sending mail through Google Mail

I was trying to get my Lift web application to send out some mail through a Gmail account. I'm rusty with Java Mail so this took longer than it should have, so here's the code for anyone else it helps. The first big of code is just a bit of code to insert into the Boot class. I've put it in a separate method just to keep this code together, then I call it straight from the boot method.

import javax.mail.{PasswordAuthentication, Authenticator}

  private def setupMailerForGmail() {
    // Set up mailing to mail through Gmail account
    System.setProperty("mail.smtp.starttls.enable", "true")
    System.setProperty("mail.smtp.ssl.enable", "true")
    System.setProperty("mail.smtp.host", "smtp.gmail.com")
    System.setProperty("mail.smtp.auth", "true")

    // Turn on display of emailing processing logs by setting this property...
    //System.setProperty("mail.debug", "true")

    Mailer.authenticator = Full(new Authenticator {
      override def getPasswordAuthentication =
        new PasswordAuthentication("accountname…@gmail.com", "password…")
    })

  }

To send an email you can use something as short as:

import net.liftweb.util.Mailer.{To, From, PlainMailBodyType, Subject}
import net.liftweb.util.Mailer
…
    Mailer.sendMail(From("accountname…@gmail.com"), Subject("Just a test"),
      List(PlainMailBodyType("The body of the test message"), To("recipient_email_address…")) : _*)

Once this is working it's relatively straightforward to work out how to do XHTML mails and send to multiple recipients, etc.

The one bit of code that helped me the most was setting the mail.debug system property which caused the Java Mail code to output a trace of the mail sending process and allowed me to spot that I had failed to enable SSL.

Pragmatic Scala: Parsing columns from plain text

A few days ago I was preparing for a meeting and I thought I'd print out a list of all the attendees from the Eventbrite event details.

When I looked at the list I saw that it seemed to be in no particular order and didn't print very well so I thought, "I wonder if I could copy and paste this into a spreadsheet and sort it by surname". Unfortunately each entry had one or two lines and variable information in it and was delimited by spaces and commas.

Then I thought, hmm, I could process this quickly with a bit of Scala and pattern matching.

There's nothing clever here, but for me it's quite significant that the effort involved in writing this code was so low that I was able to use Scala to solve this problem there and then and it worked seamlessly. I've posted it here because there are too few simple examples of Scala lying around the web for people to get started with.

So here's the code if you're interested…

#!/bin/sh
exec scala "$0" "$@"
!#

import java.io.File
import scala.io.Source

val source = Source.fromFile(new File("Attendees.txt"))
val lines = source.getLines.trim
lines.foreach( line => {
val (details, presentation) = line.split("\t").toList match {
  case List(d) => (d,"")
  case List(d,p) => (d,p)
}
val (name, position, organisation) = details.split(", ").toList match {
  case List(n) => (n,"","")
  case List(n,c) => (n,"",c)
  case List(n,p,c) => (n,p,c)
  case List(n,p,d,c) => (n,p+ ", "+d,c)
}
val (first, middle, last) = name.split(" ").toList match {
  case List(f) => (f,"","")
  case List(f,l) => (f,"",l)
  case List(f,m,l) => (f,m,l)
}

println(List(first,middle,last,position,organisation,presentation).mkString("\t"))
})

It was parsing lines of text which looked roughly like this:

Firstname [Middlename] Surname, [[Position, [Department ,]]Company][\t Presentation]
(e.g. bits in square brackets were optional).

For those unfamiliar with Scala, the first three lines just allow the code to be run as a script on the command line just like any shell script. Then the lines.foreach( line => code just loops through each line of code setting line equal to that line. The nice bit is the matching parts which assign values to multiple values at once so:

 val (details, presentation) = line.split("\t").toList match {
  case List(d) => (d,"")
  case List(d,p) => (d,p)
}
effectively says:
  • Assign to the variables: details and presentation at once, the value of the following expression.
  • Take the line and convert it to an array of Strings by separating it at every tab character, then convert the array to a List.
  • Match the List to one of two patterns:
  • If it matches the pattern of a List with one entry then assign the value of that entry to d and return the thing on the right hand side of the =>. In this case it is a tuple (pair of values): d and an empty String.
  • If it matches the pattern of a List with two entries then assign d to the first and p to the second and then return them both as a tuple.

So, at the end we have details set to everything before the tab and presentation set to everything after the tab or an empty string if there was no tab.

However, if there are two or more tabs then none of the patterns match so the program creates a runtime error which is great because we know that the program is either doing what it was meant to or not.

Wednesday, 13 May 2009

An end to restart problems on Mac OS 10.5.7

I've been running on 10.5.7 for a little while before the official release and having problems with the machine refusing to shutdown properly. Yesterday I ran across a discussion board support comment that recommended removing items from your home directory ~/Library/Plug-ins directory and removing the top level /Library/Preferences/com.apple.loginwindow.plist file.
I don't know which one solved the problem because I couldn't be bothered doing one at a time, but I ended up removing an old DiskImages directory in my plug-ins which had a VirtualPCDiskImagePlugin.bundle in it that seemed to be creating errors in my log at startup, and I removed the loginwindow.plist file. Now everything seems to be working smoothly again!
This post marks a return to blogger, because I've decide to blog again from time to time and it's the easiest option for me right now!

Monday, 14 March 2005

This blog has moved

I have now moved this blog to a Moveable Type based blog providing categories and TrackBack facilities.

The new URL for the blog is www.typingahead.com/management/.

The syndication feed has also changed and can be obtained either as RSS or Atom.

Please update any bookmarks or RSS subscriptions to see new posts. At some point in the future this site will be taken down.

Friday, 25 February 2005

PRINCE2 Open Exam booking workaround

Attempting to formalise my PRINCE2 knowledge has been frustrated by the fact that the Open Examinations in the UK conducted by APM Group are booked through a web site booking form which which uses some outdated JavaScript to display available booking slots. From my testing this appears to only work on Internet Explorer on a PC, though Internet Explorer on the Mac will display the options even if you can't book them!

I'll see if I can persuade them to fix this, but in the meantime, if you are a user of Firefox or Safari you can circumvent their JavaScript museum by typing the following line (as one long line) into the location bar and hitting Return:

javascript:var str=document.f.T1.value; document.getElementById("Topic").innerHTML=str; document.getElementById("Topic").style.visibility = "visible"; alert("Done!");

Replace "T1" (for Milton Keynes) in the above with "T2" for Winsford or "T3" for York.

Once the dates are displayed you can proceed as normal.

 
Google Analytics Alternative