Change the priority of incoming mail (incl. Apple Mail)

… or, ‘the sender that cried emergency’.

Before I get into this article I’d first like to point out that this solution was not born out of anger, hostility, or any other negative vibe. It’s simply a usability and project management issue.

The Problem

We probably all have a sender or two that abuse the Priority setting of email messages. Perhaps they honestly think many of their message are actually very important. And that’s fine, priority can be objective. But it does cause a problem when checking email.

  • Just like The Boy Who Cried Wolf, a sender that sets too many messages to High Priority runs the risk of being ignored. That certainly is not good for the sender.
  • When other senders don’t use the priority setting, those messages get deferred. Not necessarily a good thing either.
  • Turning off the Priority column to cut down the noise makes legitimately important messages look normal priority.
  • Turning off the Priority column to cut down the noise also gets rid of the ‘Flagged’ designation.

So basically speaking, someone who abuses the priority setting can really muck up the works. And you can’t really them about it either.

Some email programs let you change the priority of incoming mail. I use Apple’s Mail as a mail client and it does not. I checked out scripts, plugins, even a workaround of moving the message to the Drafts mbox, change the priority, then move it back to the in mbox… which is not good because then it sets you as the sender. D’oh! I also tried editing the emlx file on the hard drive but that didn’t work, I guess because I’m using IMAP. What then can we do?

The Fix

What we need to do is target those few senders, reset the priority of their incoming messages, and add a visual clue that it was changed. All other senders should not be affected.

The fix is dependent on the mail server software. I’ll show how to do this with SmarterMail since that’s what I use. We’ll set up a Content Filter to look for high priority messages from a certain sender, and add an action to reset the message’s priority.

1) Click the Settings button, expand My Settings, expand Filtering, then click Content Filtering. Your list may be blank. Mine already has three set up. Just click New to get started.

2) Turn on ‘From specific address’ and ‘Flagged as high priority’ and then click Next.

3) Make sure ‘AND’ is selected. Enter email addresses for the target senders.
Click Next.

4) Now finally the magic. Give this filter a Name. Turn on ‘Add Header’ and enter in whichever header name/value your email program listens to. For priority, Apple Mail uses the mail header “X-Priority”.  That is what I set to 0 (zero). Other mail clients use “Importance” and “X-MSMail-Priority”. Either of those you set to “Medium” instead of 0.
I also prefix the subject with an asterisk. That way I still know the sender thought this message was important, without gumming up everything else.
Click Save.

5) Send yourself a high priority test message. When it comes in, you should see that the Flag column is blank and there is now an asterisk in front of the Subject. When you see the asterisk, feel free to giggle like a school girl, ‘tee hee!’

Also take a look at the raw source. You’ll see that the the original X-Priority of 1 was overwritten with a zero.

Hooray, it works! =)

Want to read more?

WordPress – 301 location to sub page

WordPress is great for blogging but still has a way to go to be a CMS. One thing I find odd is that you can create Categories for Posts but not for Pages. Usually a client will want pages categorized for navigation. So this becomes a problem. Sure you can nest Pages (parents and children) but that means you must have content in every menu item.

After a quick google search I came across some code that allows WP’s Pages to have empty menu items for categorization. Or at least that’s the visual effect. The fix is to create a Template in your theme with some PHP code. It redirects the browser to the first Child Page:

<?php
/*
Template Name: Redirect To First Child
*/
if (have_posts()) {
  while (have_posts()) {
  the_post();
  $pagekids = get_pages("child_of=".$post->ID."&sort_column=menu_order");
  $firstchild = $pagekids[0];
  wp_redirect(get_permalink($firstchild->ID));
 }
}
?>

This works but I’m not too fond of it. It uses a refresh. I tweaked it a bit. Changed the wp_redirect to a Location header and added a 301 status code:

<?php
/*
Template Name: 301 Redirect To First Child
*/
if (have_posts()) {
 while (have_posts()) {
  the_post();
  $pagekids = get_pages("child_of=".$post->ID."&sort_column=menu_order");
  $firstchild = $pagekids[0];
  header("HTTP/1.1 301 Moved Permanently");
  header("Location: ".get_permalink($firstchild->ID));
  exit();
 }
}
?>

This is much faster on the front end. It also tells search engines not to index those blank categorization pages.

<?php/*Template Name: 301 Redirect To First Child*/if (have_posts()) {  while (have_posts()) {    the_post();    $pagekids = get_pages(“child_of=”.$post->ID.”&sort_column=menu_order”);    $firstchild = $pagekids[0];   header(“HTTP/1.1 301 Moved Permanently”);   header(“Location: “.get_permalink($firstchild->ID));   exit();  }}?>

Updated compressed scripty 1.8.3 for LightView, PHP

I ran across a problem with LightView which is stated as requiring Prototype 1.6.1 and Scriptaculous 1.8.2. Yet it was failing even when I had scriptaculous 1.8.3 loaded.

Apparently LightView looks for the loader scriptaculous.js rather than the actual components (effect, builder, etc).

My previous compressed Prototype 1.6.1 and Scriptaculous 1.8.3 did not have the loader/stub scriptaculous.js file. Ideally, that’s never needed as long as you load the other scriptaculous js files.

So here is an updated package. Also in this archive is the PHP version of the ColdFusion file to server the jgz.

The combined file is now 273KB. The load order is as follows:

  • prototype
  • scriptaculous
  • builder
  • effects
  • dragdrop
  • controls
  • slider
  • sound

It includes all comments and credits. I gzipped it down to 62KB.

You’d load it like so:

<script type="text/javascript" charset="ISO-8859-1" src="/includes/js/scriptaculous/scriptaculous.cfm"></script>

Download it: wv-scripty-183.zip

Custom scrollbars in Adium – ‘Elegant Simple’ Message Style

Visually based on the “Pretty Simple” Message Style by Piotrek Marciniak, I’ve created a new breed of Adium Message Style – which boasts a completely custom scrollbar.

This message style is a working proof of concept. It is a prototype for the talented folks that create  wonderful message styles. I’m a developer, not an artist. I hope that others will use it as a spring board for rapid development of a whole new breed of message styles with custom scrollbars.

Since Adium Message Styles are really web pages, it only seemed right to mash up Prototype JS, LivePipe UI and Scriptaculous!

Features

  • Fade-in of messages
  • Auto smooth scrolling when new message is received
  • Custom styled scrollbar
  • Dynamic height scrollbar handle
  • Header and Footer objects of scrollbar handle
  • Auto-hiding and fading scrollbar (mouse in/out of window)
  • Mouse wheel support

[media id=11 width=600 height=470]

( View full size 800×600 MP4 3.7MB )

Go and get it!

Compressed Prototype 1.6.1 and Scriptaculous 1.8.3

I created a new compressed file for Prototype 1.6.1 and Scriptaculous 1.8.3. Included is my modified sound.js.

The combined file is 268KB. The load order is as follows:

  • prototype
  • builder
  • effects
  • dragdrop
  • controls
  • slider
  • sound

It includes all comments and credits. I gzipped it down to 60KB.

For your convenience in the attached zip contains both versions and a ColdFusion file to serve the correct one. You’d load it like so:

<script type="text/javascript" charset="ISO-8859-1" src="/includes/js/scriptaculous/scriptaculous.cfm"></script>

Well, what are you waiting for? 🙂 wv-scripty-183.zip

Speeding up cffm v1.1x

I manage a site with nearly 50GB of small PDFs. Thousands of directories and files. This makes CFFM super duper slow. I know it sounds silly, but when staring at a blank window, 15 seconds feels like 15 minutes. The problem is that with every page load, the entire directory tree below your initial directory is read. Crazy. Here is the fix…

At around line 648 of cffm.cfm, only turn on recursion if this particular action requires it:

<cfset variables.listAllFiles = cffm.directoryList(cffm.includeDir, (isdefined("url.action") and url.action eq 'copymoveForm'))>

… which is, when moving or copying. In my application, speed increased 10x.
And to get a little more speed when listing a directory with images…

At around line 67 of cffm.cfm, turn off image sizes:

<cfinvokeargument name="enableImageDimensionsInDirList" value="true">

CFSelect with multiple query columns

CFSelect is nice because it can help you write out some code quicker. Just like the rest of ColdFusion. But I never used it because so many times I needed to display two columns in the <option>, such as “#lastName#, #firstName#”.

While working on a site I fell into the same routine. I start typing out CFSelect then grit my teeth when I get to the Display attribute. Being stubborn about it I stumbled upon a nice MySQL function called CONCAT(). Using that one can merge two columns in the query to be output as a single column name. Like so:

<cfquery name="emps" datasource="#application.datasource#">
SELECT
 id, CONCAT(lastname, ', ', firstname) AS fullName
FROM
 employees
ORDER BY
 lastname, firstname
</cfquery>

Then simply use that column name for the display (or elsewhere needed):

<cfselect name="employeeid" query="emps" selected="" value="id" display="fullName"/>

MySQL: counts of multiple sub-items of each parent

Sometimes it is useful to show in a list the numbers of children each object has. For instance how many Products are in each Category.

That’s simple enough to do when only one child type is used:

SELECT
 categories.title, categories.id,
 count(products.id) as productCount
FROM
 categories
   INNER JOIN products ON categories.id = products.categoryid

However, if you wanted to count two separate children types, the same method of querying will give you very odd results:

SELECT
 categories.title, categories.id,
 count(products.id) as productCount, count(images.id) as imagesCount
FROM
 categories
   INNER JOIN products ON categories.id = products.categoryid
   INNER JOIN images ON categories.id = images.categoryid

The lazy programmer would get around this by using the server language – looping through a simple query of the category, and with each row run another query to count the products (and another for the images). Yuck.

Instead, I found this method to work quite well:

SELECT
 cats.title AS title, cats.ID AS id,
 COALESCE(prods.howmany,0) AS productCount,
 COALESCE(imgs.howmany,0) AS imageCount
FROM (
 SELECT title, ID
 FROM categories
) AS cats
LEFT JOIN (
 SELECT
   count(products.id) as howmany,
   products.categoryid as categoryid
 FROM products
   LEFT JOIN categories ON products.categoryid = categories.id
 GROUP BY products.categoryid
) AS prods ON cats.id=prods.categoryid
LEFT JOIN (
 SELECT
   count(images.id) as howmany,
   images.categoryid as categoryid
 FROM images
   LEFT JOIN categories ON images.categoryid = categories.id
 GROUP BY images.categoryid
) AS imgs ON cats.id=imgs.categoryid

Note the use of the ‘COALESCE()’ function so that nulls are returned as a 0 (zero).
As you can see the database is still running three queries. But they are all within one connection, and the server language didn’t do any work.  Then MySQL joins those queries together into one result, easily parsed by your server language of choice. Here, ColdFusion:

<table>
 <tr>
   <td>Category</td>
   <td>Products</td>
   <td>Images</td>
 </tr>
 <cfoutput query="read">
 <tr>
   <td>#title#</td>
   <td>#productCount#</td>
   <td>#imageCount#</td>
 </tr>
 </cfoutput>
</table>

ColdFusion clips for Coda

I have made quite a few Clips in Coda to make development a little speedier. Hopefully you can get some use out of them too.

Coda Clips
Preview of Coda Clips - keep in mind the clips window only shows the first line of each clip.

Download the Clips here:
ColdFusion Coda Clips