growl mail temp fix

The Growl forums have moved to Google Groups, this forum is read only.
User avatar
bgannin
Growl Team
Posts: 1817
Joined: Thu Dec 02, 2004 8:11 am
Location: ..here
Contact:

Postby bgannin » Fri Nov 09, 2007 4:36 am

tw,

Could you mock up or implement a proposed replacement in this vein for GrowlMail that would be on-par (or better ;)) with what currently ships? It seems like you've put a fair amount of thought and are familiar with the area, which is one of the areas in which we've been lacking.
Try my software!

#define ADIUMX pimp //by me
#define QUESTION ((2b) || (!2b))
Have you hugged a programmer today?

tw
Muffin
Posts: 28
Joined: Sat Nov 03, 2007 9:39 pm

Postby tw » Fri Nov 09, 2007 4:47 am

The_Tick wrote:Regarding the scripts, they're still in subversion, feel free to take a look at them


ok, I've got them, and I'll look them over - do they just need to be updated to current standards, or do you want me to revise them content-wise as well? I'm not precisely sure what 'maintenance' refers to in this context. :smile:

User avatar
evands
Cocoaforge Admin
Posts: 3152
Joined: Thu Dec 02, 2004 10:55 pm
Location: Decatur, GA
Contact:

Postby evands » Fri Nov 09, 2007 4:49 am

Take full ownership of the feature and make Growl in Mail awesome! If the existing scripts are helpful, use them as much as you want. If they're useless, Secure Empty Trash on 'em and start from scratch :)
The duck still burns.
--
My company: Saltatory Software. Check it out :)

tw
Muffin
Posts: 28
Joined: Sat Nov 03, 2007 9:39 pm

Postby tw » Fri Nov 09, 2007 4:53 am

bgannin wrote:tw,

Could you mock up or implement a proposed replacement in this vein for GrowlMail that would be on-par (or better ;)) with what currently ships? It seems like you've put a fair amount of thought and are familiar with the area, which is one of the areas in which we've been lacking.


sure, give me a few minutes (well, maybe a few more than that - I'm just off to get dinner). as I was telling the_tick, though, the one major deficit applescript has (currently) is that there's no support in GrowlHelperApp for clicking on notifications. but setting that aside, the rest is straightforward.

User avatar
bgannin
Growl Team
Posts: 1817
Joined: Thu Dec 02, 2004 8:11 am
Location: ..here
Contact:

Postby bgannin » Fri Nov 09, 2007 4:59 am

We'll look to address that, and having a compelling reason to makes it that much harder to ignore ;)
Try my software!



#define ADIUMX pimp //by me

#define QUESTION ((2b) || (!2b))

Have you hugged a programmer today?

User avatar
excomax
Frappa
Posts: 126
Joined: Tue Apr 24, 2007 2:22 am
Location: Leipzig (Germany)
Contact:

Postby excomax » Fri Nov 09, 2007 1:12 pm

Is there any way to be informed of new RSS-Messages in Mail 3.0?

Thats the one thing that would make me completely happy until GrowlMail for Mail3.0 is released. :)

Montanan
Harmless
Posts: 8
Joined: Thu Nov 08, 2007 5:07 pm

Postby Montanan » Fri Nov 09, 2007 2:04 pm

tw wrote:the one major deficit applescript has (currently) is that there's no support in GrowlHelperApp for clicking on notifications. but setting that aside, the rest is straightforward.


As someone who's used the mail notification script for a day now, I agree that this is critical. Even knowing about the issue, I've managed to inadvertently crash Growl a couple of times that way.

Montanan
Harmless
Posts: 8
Joined: Thu Nov 08, 2007 5:07 pm

Postby Montanan » Fri Nov 09, 2007 2:19 pm

... and since you managed to fulfill my first enhancement request so rapidly, here's another one. :)

This is probably tougher, though. Would it be possible to have the noteType automatically reflect the name of the mailbox in which the message has been placed? That way, the first line of the notification would also list the mail account name by default. And for those of us who use rules to sort our incoming mail into different mailboxes, we'd get a quick visual indication of that, instead. It'd be very helpful.

tw
Muffin
Posts: 28
Joined: Sat Nov 03, 2007 9:39 pm

Postby tw » Sun Nov 11, 2007 1:34 am

bgannin wrote:tw,

Could you mock up or implement a proposed replacement in this vein for GrowlMail that would be on-par (or better ;)) with what currently ships? It seems like you've put a fair amount of thought and are familiar with the area, which is one of the areas in which we've been lacking.


ok, pardon the long post.

first script I have for you is the workhorse of a growl mail script. basically what it does is look for any Mail Rule that has a name beginning with 'growl-' (case insensitive) and turns the last part of the name into a Growl notification category. this if you set up a rule called 'growl-work' and set it to recognize all of your work emails, the script will set up a 'work' notification in growl that you can then set to give its own peculiar notification type.

the normal place for this script would be in the user scripts folder, but it actually can be placed anywhere, and I'm thinking that you could just put it in Growl's resources folder and change the script URL to there...

Code: Select all

on run
   -- at current, the registration is done whenever you launch the script,
   -- and also below whenever the the script itself is run by Mail
   -- (that let's users make new notification on the fly, sort of...)
   -- could probably find a more graceful semaphor, but...
   register()
end run

using terms from application "Mail"
   on perform mail action with messages messageList for rule theRule
      set theRuleName to name of theRule
      if theRuleName does not start with "growl-" then return
      
      register()
      -- extract notification type from rule name
      set noteType to characters 7 thru (length of theRuleName) of theRuleName as text
      repeat with thisMessage in messageList
         
         -- basic information for notification
         set theSender to sender of thisMessage
         set theSubject to subject of thisMessage
         set theText to (content of thisMessage)
         set tid to AppleScript's text item delimiters
         set AppleScript's text item delimiters to " "
         try
            set theSummary to (text items 1 through 20 of theText) as text
         on error
            set theSummary to theText
         end try
         set AppleScript's text item delimiters to tid
         
         -- notify
         tell application "GrowlHelperApp" to notify with name noteType ¬
            title noteType description ¬
            "From: " & theSender & return & "Subject: " & theSubject ¬
            & return & return & theSummary ¬
            application name "Growl Mail Rule"
      end repeat
      -- if we want to coalesce or order the notifications, then we'd put the
      -- notifications into an array above and notify GHA here.  I'm not completely
      -- on the structures that are required for grouped messages, though..
   end perform mail action with messages
end using terms from

to register()
   tell application "Mail"
      set ruleList to name of every rule whose name begins with "growl"
   end tell
   set noteTypes to {}
   repeat with theRuleName in ruleList
      set end of noteTypes to (characters 7 thru (length of theRuleName) of theRuleName as text)
   end repeat
   tell application "GrowlHelperApp"
      register as application "Growl Mail Rule" all notifications noteTypes ¬
         default notifications noteTypes ¬
         icon of application "Script Editor"
   end tell
end register


the second script is the installer script, and it ended up being more of a hack than I'm entirely comfortable with. while rule actions themselves work perfectly fine, applescripting them seems to be totally whacked (you can create rules, but they don't seem to hold conditions when you set them; I need to play with it some more). what I did then, was write a script that just modified the MailRules,plist file directly, but mail doesn't seem to be accepting new rules that way (not that it can't or won't; I've tested with vanilla cut and pastes that work fine, I'm just doing something wrong setting up the dictionary elements that I haven't sussed out yet). basically, when I get this working it will add rules for mail type, defined address groups, and accounts. I'm thinking, however, that to do this elegantly would require an applescript studio effort (the dialogs in standard applescript are too wimpy...)

this requires the satimage XMLLib osax, incidentally; good enough for a mockup. and I recommend that if you want to play with it you make a backup copy of tour ~/Library/Mail/MessageRules.plist file before modifications - this script does not work the way it should, and may freeze Mail (though to date I've lost no data from it.)

Code: Select all

 -- delete: improved (i.e. working) code below


EDIT: bug fix on the workhorse script above, thanks to milksheikh. added try block to handle message lengths less than 20 words.
Last edited by tw on Wed Nov 28, 2007 8:36 am, edited 2 times in total.

tw
Muffin
Posts: 28
Joined: Sat Nov 03, 2007 9:39 pm

Postby tw » Sun Nov 11, 2007 1:36 am

excomax wrote:Is there any way to be informed of new RSS-Messages in Mail 3.0?

Thats the one thing that would make me completely happy until GrowlMail for Mail3.0 is released. :)


well, there's a mail rule for it, but (not having an RSS feeds set up) I'm not in a place to test it right now, so I don't really know how it works.

tw
Muffin
Posts: 28
Joined: Sat Nov 03, 2007 9:39 pm

Postby tw » Sun Nov 11, 2007 1:50 am

Montanan wrote:... and since you managed to fulfill my first enhancement request so rapidly, here's another one. :)

This is probably tougher, though. Would it be possible to have the noteType automatically reflect the name of the mailbox in which the message has been placed? That way, the first line of the notification would also list the mail account name by default. And for those of us who use rules to sort our incoming mail into different mailboxes, we'd get a quick visual indication of that, instead. It'd be very helpful.


from the original script I posted (not the one I just did), first, change the 'on performing' line to read

Code: Select all

on perform mail action with messages messageList for rule theRule


then later, where it says 'title noteType', change that to read 'title (get name of move message of theRule)'. the move message element is where mail stores a pointer to the destination box

tw
Muffin
Posts: 28
Joined: Sat Nov 03, 2007 9:39 pm

Postby tw » Sun Nov 11, 2007 1:53 am

evands wrote:Take full ownership of the feature and make Growl in Mail awesome! If the existing scripts are helpful, use them as much as you want. If they're useless, Secure Empty Trash on 'em and start from scratch :)


lol - yikes! ok, I'll check them out. the duck still burns indeed...

tw
Muffin
Posts: 28
Joined: Sat Nov 03, 2007 9:39 pm

Postby tw » Mon Nov 12, 2007 2:16 am

new version of the second script above - this one should work, though I want to let it sit for a few days on my machine and see if any issues manifest...


Code: Select all

set isVerbose to false
set ifMailScriptingActuallyWorks to false
set theScriptPath to (((path to scripts folder) as string) & "Growl Mail Rules Script.scpt") as file specification

set accountList to getEmailAccounts()
set groupList to getAddressBookGroups()

if isVerbose is true then
   if (count of accountList) is greater than 1 then
      set accountList to choose from list accountList with prompt "Choose which Account(s) you would like to have special notifications..." OK button name "Choose these" cancel button name "Never Mind" with multiple selections allowed
   end if
   if (count of groupList) is greater than 1 then
      set groupList to choose from list groupList with prompt "Choose which Address Book group(s) you would like to have special notifications..." OK button name "Choose these" cancel button name "Never Mind" with multiple selections allowed
   end if
else
   set accountList to {}
   set groupList to {}
end if

if ifMailScriptingActuallyWorks then
   tell application "Mail"
      repeat with thisItem in groupList
         set newRule to make new rule at the end of rules with properties {|name|:"growl-" & thisItem, |run script|:theScriptPath, |stop evaluating rules|:true}
         make new rule condition at end of rule conditions of newRule with properties {|rule type|:sender is member of group, |expression|:thisItem}
      end repeat
      repeat with thisItem in accountList
         set newRule to make new rule at the end of rules with properties {|name|:"growl-" & thisItem, |run script|:theScriptPath, |stop evaluating rules|:true}
         make new rule condition at end of rule conditions of newRule with properties {|rule type|:account, |expression|:thisItem}
      end repeat
      set newRule to make new rule at the end of rules with properties {|name|:"growl-basic", |run script|:theScriptPath, |stop evaluating rules|:true}
      make new rule condition at end of rule conditions of newRule with properties {|header|:"AnyMessage"}
      
   end tell
else
   tell application "Mail" to quit
   set i to 1
   set mailRulesPath to alias (((path to library folder from user domain) as text) & "Mail:MessageRules.plist")
   set theRulesPlist to (PlistOpen mailRulesPath)
   set rulesArray to PlistChild theRulesPlist key "rules"
   set plistTemplate to {|Active|:"1", |AllCriteriaMustBeSatisfied|:"NO", |AppleScript|:"~/Library/Scripts/Applications/Mail/growl mail rule.scpt", |AutoResponseType|:0, |Criteria|:{}, |Deletes|:"NO", |HighlightTextUsingColor|:"NO", |MarkFlagged|:"NO", |MarkRead|:"NO", |NotifyUser|:"NO", |RuleId|:"", |RuleName|:"", |ShouldCopyMessage|:"NO", |ShouldTransferMessage|:"NO"}
   set groupCriteriaTemplate to {|CriterionUniqueId|:"", |Expression|:"", |GroupId|:"", |GroupName|:"", |Header|:"SenderIsMemberOfGroup"}
   repeat with thisGroup in groupList
      -- for the time being, skip already established rules
      if (PlistMatch jill key "RuleName" value "Growl-" & name of thisGroup) is equal to {} then
         set GroupName of groupCriteriaTemplate to name of thisGroup
         set Expression of groupCriteriaTemplate to name of thisGroup
         set GroupId of groupCriteriaTemplate to id of thisGroup
         set CriterionUniqueId of groupCriteriaTemplate to (do shell script "uuidgen")
         set Criteria of plistTemplate to {groupCriteriaTemplate}
         set RuleName of plistTemplate to "Growl-" & name of thisGroup
         set RuleId of plistTemplate to (do shell script "uuidgen")
         set newKid to PlistNewChild plistTemplate at rulesArray index i
         set i to i + 1
      end if
   end repeat
   set accountCriteriaTemplate to {|AccountURL|:"", |CriterionUniqueId|:"", |Expression|:"", |Header|:"Account"}
   repeat with thisAccount in accountList
      -- for the time being, skip already established rules
      if (PlistMatch jill key "RuleName" value "Growl-" & name of thisAccount) is equal to {} then
         set AccountURL of accountCriteriaTemplate to URL of thisAccount
         set Expression of accountCriteriaTemplate to path of thisAccount
         set CriterionUniqueId of accountCriteriaTemplate to (do shell script "uuidgen")
         set Criteria of plistTemplate to {accountCriteriaTemplate}
         set RuleName of plistTemplate to "Growl-" & URL of thisAccount
         set RuleId of plistTemplate to (do shell script "uuidgen")
         set newKid to PlistNewChild plistTemplate at rulesArray index i
         set i to i + 1
      end if
   end repeat
   set typeCriteriaTemplate to {|CriterionUniqueId|:"", |Expression|:"", |Header|:"MessageType", |Qualifier|:"IsEqualTo"}
   repeat with j from 0 to 2
      set |Expression| of typeCriteriaTemplate to (j as text)
      set |CriterionUniqueId| of typeCriteriaTemplate to (do shell script "uuidgen")
      if j = 0 then
         set |RuleName| of plistTemplate to "Growl-Mail"
      else if j = 1 then
         set |RuleName| of plistTemplate to "Growl-RSS Account"
      else
         set |RuleName| of plistTemplate to "Growl-Note"
      end if
      set |Criteria| of plistTemplate to {typeCriteriaTemplate}
      set |RuleId| of plistTemplate to (do shell script "uuidgen")
      set newKid to PlistNewChild plistTemplate at rulesArray index i
      set i to i + 1
   end repeat
   set basicCriteriaTemplate to {|CriterionUniqueId|:"", |Header|:""}
   repeat with j from 0 to 1
      if j is equal to 0 then
         set |Header| of basicCriteriaTemplate to "IsJunk"
         set |RuleName| of plistTemplate to "Growl-Junk"
      else
         set |Header| of basicCriteriaTemplate to "AnyMessage"
         set |RuleName| of plistTemplate to "Growl-All"
      end if
      set |CriterionUniqueId| of basicCriteriaTemplate to (do shell script "uuidgen")
      set |Criteria| of plistTemplate to {basicCriteriaTemplate}
      set newKid to PlistNewChild plistTemplate at rulesArray index i
      set i to i + 1
   end repeat
   PlistSave theRulesPlist
   PlistClose theRulesPlist
end if

-- register
set categoryList to {"All", "Junk", "Note", "Mail", "RSS Account"} & groupList & accountList
tell application "GrowlHelperApp"
   register as application "Growl Mail Rule" all notifications categoryList ¬
      default notifications categoryList ¬
      icon of application "Script Editor"
end tell

to getEmailAccounts()
   set aList to {}
   
   set thePlistFile to PlistOpen alias (((path to preferences from user domain) as text) & "com.apple.mail.plist")
   set theAccountArray to PlistChild thePlistFile key "MailAccounts"
   repeat with i from 1 to PlistCount theAccountArray
      set thisAccountDictionary to PlistChild theAccountArray index i
      if (PlistGet thisAccountDictionary key "AccountType") is in {"POPAccount", "IMAPAccount"} then
         if ("IsActive" is not in (PlistGetKeys thisAccountDictionary)) or ((PlistGet thisAccountDictionary key "IsActive") is not "NO") then
            set theName to PlistGet thisAccountDictionary key "AccountName"
            set theMailboxPath to PlistGet thisAccountDictionary key "AccountPath"
            set tid to AppleScript's text item delimiters
            set AppleScript's text item delimiters to "-"
            set theEmail to text item 2 of (PlistGet thisAccountDictionary key "AccountPath")
            set AppleScript's text item delimiters to tid
            if (PlistGet thisAccountDictionary key "AccountType") is "POPAccount" then
               set theurl to "pop://" & theEmail
            else
               set theurl to "imap://" & theEmail
            end if
            set end of aList to {name:theName, path:theMailboxPath, URL:theurl}
         end if
      end if
   end repeat
   PlistClose thePlistFile
   return aList
end getEmailAccounts
to getAddressBookGroups()
   set metaDataPath to (((path to application support from user domain) as text) & "AddressBook:Metadata:")
   set gList to {}
   tell application "Finder"
      set groupList to every file of folder metaDataPath whose name contains "Group"
   end tell
   repeat with thisGroupPlist in groupList
      set thisGroupPlist to thisGroupPlist as alias
      set thePlistFile to (PlistOpen thisGroupPlist)
      
      set end of gList to {name:(PlistGet thePlistFile key "GroupName"), id:(PlistGet thePlistFile key "UID")}
      PlistClose thePlistFile
   end repeat
   return gList
end getAddressBookGroups

tomyknoker
Harmless
Posts: 7
Joined: Tue Mar 28, 2006 2:08 am

Postby tomyknoker » Tue Nov 13, 2007 12:49 am

I'm really confused... Do I use the code from the OP or this new code?

tw
Muffin
Posts: 28
Joined: Sat Nov 03, 2007 9:39 pm

Postby tw » Tue Nov 13, 2007 1:13 am

tomyknoker wrote:I'm really confused... Do I use the code from the OP or this new code?


sorry, didn't mean to confuse you. this last script is something that the developers asked for - you don't need to use it. if you just want to use a script to have growl notifications, and you're not averse to working with applescript a bit, use the first script from the original post, or maybe the script in the Nov 10, 5:34 pm post above. the difference between the two scripts is that the original post is a simple 'let's get it to work' script, while the second is a 'let's make it work in a general way' script.

give them a try, and post again if you have issues.

tomyknoker
Harmless
Posts: 7
Joined: Tue Mar 28, 2006 2:08 am

Postby tomyknoker » Tue Nov 13, 2007 1:22 am

tw you're a legend worked so well... ok so with the last script you posted above is that a little better? should i use that instead?

tw
Muffin
Posts: 28
Joined: Sat Nov 03, 2007 9:39 pm

Postby tw » Tue Nov 13, 2007 1:54 am

tomyknoker wrote:tw you're a legend worked so well... ok so with the last script you posted above is that a little better? should i use that instead?


the very last script (the long one that begins set isVerbose to false) - that's intended as an automatic installer and setup script. it's a rough example only, and you don't need it, so I'd ignore it if I were you.

the main difference between the original and the second script is that the latter one searches fro Mail Rule names that begin with 'Growl-' and automatically registers them (well, on the second pass...). otherwise they operate the same.

Sketchwork
Harmless
Posts: 1
Joined: Tue Nov 13, 2007 7:55 pm

Postby Sketchwork » Tue Nov 13, 2007 8:01 pm

I must admit i had issues getting this script to work optimally in my Mail. Since Mail lacks some serious rule abilities (mostly a NOT function, or a NOT junkmail), i had to set up a double rule to handle this. In order, rules ran accordingly:

(pseudocode with mail junk filtering set for AFTER my rules)
1-5. my normal rules
6. Growl_Is_Junk
-- if "mail is junk mail"
---- stop running rules
7. Growl_Pass
-- If "subject does not contain ***SPAM***"
---- run applescript growlnotifier

What i find happening is that for some reason only certain emails actually trigger the 7th rule. I can send identical test emails to myself, and sometimes they will trigger the 7th rule, and sometimes not. And in no case do they trigger the first 6 in any way.

Mail in Leopard clearly has several issues of its own, and i think its filtering is one of them.

tw
Muffin
Posts: 28
Joined: Sat Nov 03, 2007 9:39 pm

Postby tw » Tue Nov 13, 2007 10:11 pm

Sketchwork wrote:I must admit i had issues getting this script to work optimally in my Mail. Since Mail lacks some serious rule abilities (mostly a NOT function, or a NOT junkmail), i had to set up a double rule to handle this. In order, rules ran accordingly:

(pseudocode with mail junk filtering set for AFTER my rules)
1-5. my normal rules
6. Growl_Is_Junk
-- if "mail is junk mail"
---- stop running rules
7. Growl_Pass
-- If "subject does not contain ***SPAM***"
---- run applescript growlnotifier

What i find happening is that for some reason only certain emails actually trigger the 7th rule. I can send identical test emails to myself, and sometimes they will trigger the 7th rule, and sometimes not. And in no case do they trigger the first 6 in any way.

Mail in Leopard clearly has several issues of its own, and i think its filtering is one of them.


well, I'm not sure what your first five rules are (as long as they don't reference the applescript, growl should have no effect on them whatsoever). I think that mail filters junk prior to running the rules, so if you want to run this growl script to notify about junk mail you have to attach it to the junk mail rules in the advanced junk mail setting. all rule 6 will catch is junk emails the built-in junkcatcher misses

plus, if any of the first five rules move the email out of the inbox (or have the 'stop evaluating rules' option set) then rule 7 won't catch those, either.

if you could post the details on all of your rules (easiest way is to open ~/Library/Mail/MessageRules.plist in a text editor and copy it directly into the post - removing personal info, of course) that would make it easier to see what's going on.

User avatar
Jax
Latté
Posts: 73
Joined: Wed Mar 09, 2005 7:10 pm

Postby Jax » Wed Nov 14, 2007 8:36 pm

Hey,
This is a really cool hack! Thanks for posting it!

One request: Is there any way to make the notifications sticky? That way if I'm away from my computer I'll know if I got new mail. I have a series of filters putting my email away in various folders so the mail dock icon never updates and the sticky notifications would be very helpful until a Leopard friendly version of Dock Badger comes out.


Return to “Growl”

Who is online

Users browsing this forum: No registered users