Viewing page 1 of 64

MailSlurper 4.0 Released

Written by Adam Presley on 06/04/2014 at 09:40 PM

MailSlurper 4.0 has just been released. This update addresses some bugs in parsing attachments and date display. It also adds the ability to choose from one of the following storage engines:

  • SQlite
  • MySQL
  • Microsoft SQL Server

This enhancement is one of several planned to make MailSlurper not only useful to individuals developing locally, but also to development teams in shared environments. So go grab the latest from Github!

MailSlurper 4.0

Happy coding!

MailSlurper 3.5 Released

Written by Adam Presley on 06/02/2014 at 05:21 PM

I have just published a small but important update to MailSlurper. Previously mails with attachments would cause issues with the parser and would not display correctly in the administrator. This has been addressed. In fact you can now see that a mail has attachments and even view them! So go get the latest version 3.5 on Github. Happy coding!

Parsing Woes in MailSlurper

Written by Adam Presley on 05/29/2014 at 10:37 PM

Tonight as I was working a bug in MailSlurper I quickly came to the realization that my parsing routine sucks. The current version is passable for simple text emails or basic HTML emails. But the moment you add attachments or inline images it all goes downhill. The further I dove into this problem the more I also realized that RFC 2822, or Internet Message Format and MIME are also a little dated and weird.

Basically a mail is broken down into two major parts. The first part is headers. Headers are key/value pairs separated by a colon, each set separated by a carriage return and line feed (\r\n for you nerds out there). This describes what to expect, such as the subject of the message, the sender, recipients, and more. After that another set of \r\n indicates we are ready for the second half of the mail, which is called the body. This contains the content of your email message. It also houses an HTML version of your mail if you used fancy things like links and italics, and it will also have Base64 encoded data for each attachment in your email.

To separate the mail message from the attachments the MIME specification defines what is called a boundary. This is an identifier in a specific format that comes before each attachment or section of the body. In learning all this though I started to see some complexity creep in. When the email is multipart, or contain attachments or pretty body content (HTML), the boundary gets slapped in on the end of the Content-Disposition header. So if Content-Disposition had a value already, it now has a semicolon, then the boundary marker definition.

Attachments commit the same evil in their version of the Content-Disposition header by having the file name follow after a semicolon. The is unfortunate because it muddies up my header parsing piece. I now have to be on the lookout for specific headers having additional information, which changes how I need to parse the body. If there is no boundary marker then I don't have any attachments or HTML to pull out. If I do, then parsing headers for attachments I have to look at that SAME header name of Content-Disposition but look for a different key for the file name. Ick.

There isn't really a point to this post except for me to rant and organize my thoughts a bit. This won't be hard to do, but it will take a bit of reogranizing my parsing code.

Only Saving When File Is Modified

Written by Adam Presley on 05/15/2014 at 08:48 AM

I got a ticket the other day questioning why my Sublime Text View In Browser plugin saves the file they are viewing every time the plugin is used. The answer of course is because it must be saved prior to opening in the browser. However the poster of the ticket did have a good point. There is no need to save the user's file if the file hasn't actually changed. I have pushed a modification to the plugin to ensure that the save only occurs if the user's file has any modifications.

To do this in Sublime's API turned out to be very simple.

if self.view.is_dirty():
    self.view.window().run_command("save")

The view object gives my plugin insight into the current view, or file being worked on. Sublime provides a nice method named is_dirty() which will tell me if the current view has any pending modifications. If it does I perform the save command. If not the rest of the plugin runs and your file is opened in your browser of choice.

Google Analytics Integrated Into Texo Dashboard

Written by Adam Presley on 05/12/2014 at 11:11 PM

Tonight I have integrated a few reports from Google Analytics into the Texo adminstrator Dashboard. I have included a Visits vs New Visits, Browser Stats, and Page Traffic information. Now I don't have to log in to the Google Analytics dashboard unless I really want to dig into stats. Most often I just want to see page views and what posts are getting the most hits.

Google Analytics Screenshot

To put these graphs on my dashboard I opted to use a 3rd party library called OOCharts. Their service hooks up to your Google account and provides a simplified API for retrieving charts and chart data. For example the code the retrieve the Browser usage pie chart looks like this.

oo.setAPIKey("MyAPIKey");
oo.load(function() {
    var
       browsers = new oo.Pie("MyProfileId", "30d");

    browsers.setMetric("ga:visits", "Visits");
    browsers.setDimension("ga:browser");

    browsers.draw("browserChart");
});

When you include the oocharts.js file on your page, or inject it using RequireJS in my case, you get a global variable called oo to use for interacting with the OOCharts API. The first activity you must perform is to initialize the library with your API key. An API key is retrieved from the OOCharts site when you sign up and link to your Google account. After this you need to call the load() function and provide it a callback function in which you can do all your chart initialization.

In our callback function we are setting up a new pie chart by initializing the constructor to the Pie object, passing in a profile ID and the duration of time in which to report on. In this example we are getting 30 days worth of data. Profile ID is another piece of data retrieved from either the OOCharts site or the Google Analytics dashboard. Next I am telling the Pie instance that I want to get visitor data (ga:visits) and report against browser usage (ga:browser). The final step is to call the draw() method passing in the ID of the div that will contain my chart.

OOCharts is a quick way to get started getting Google Analytics in your web application. I am impressed with how easy it was to get started. And now my dashboard has pretty charts! Yay, and happy coding!

Tags