email entries to Mori

Tags ( | )

This script was a request from this thread

[Edit Feb 20 2006: I've added the "pre-built" version of Gordon's script which is a little more refined than the "sendMailToMori" version below, and listed in full in his reply to this thread. You can also find a copy in his script package.]

Basically you can email yourself a message that has the tag "[Mori]" in the subject (with the brackets, but not the quotes) and with the proper mail rule set it will automatically be exported to Mori.

Usage
1. Put this script anywhere.
2. Make a new mail Rule that says: If the subject contains [Mori]; run Applescript sendMailToMori
3. send yourself an email that has [Mori] in the subject

Customizing the script
1. you can change the tag to anything. just change the line that says "property sentTag: "[Mori]"
2. exported messages can be automatically deleted if you uncomment the line for this.
3. alternatively, exported messages can be archived to another mailbox. default is "sentToMori"

Possible improvements:
1. Right now it just sends the message to the front Mori document. It might be possible to chose in advance specifically which document will receive the messages.

2. The script will crash if you have the archive line uncommented, but do not have a mailbox with the expected name.


property sendTag : "[Mori]"
property sentEntriesBox : "sentToMori"

tell application "Mail"
set moriMail to every message of inbox whose subject contains sendTag
repeat with eachItem in moriMail
set subjectLine to the subject of eachItem
set subjectLine to my cleanSubject(subjectLine)
set dateLine to the date sent of eachItem
set notePart to the content of eachItem

try
my sendEntry(subjectLine, dateLine, notePart)

--uncomment the next line if you want the item to be deleted after it is sent
--delete eachItem

--uncomment the next line if you want the item to be moved to a new mailbox after it is exported to Mori. If you're going to use this method, make sure you have a mailbox named the same a the property sentEntriesBox above.

--move eachItem to mailbox sentEntriesBox

end try
end repeat
end tell

on sendEntry(subjectLine, dateLine, notePart)
tell application "Mori"
tell front document

--make sure there's an inbox to receive the new entry
if exists entry named "Inbox" of root entry then
set inFolder to entry named "Inbox" of root entry
else
set inFolder to (make new entry with properties {name:"Inbox", content type:"public.folder"})
end if

make new entry at end of entries of inFolder with properties {name:subjectLine, note:notePart, creation date:dateLine}

end tell
end tell
end sendEntry

on cleanSubject(theText)
--removes sendTag
set saveDelim to AppleScript's text item delimiters
set AppleScript's text item delimiters to {sendTag}
set theList to every text item of theText
set AppleScript's text item delimiters to {""}
set theText to theList as text
set AppleScript's text item delimiters to saveDelim
return theText
end cleanSubject

Version: 0.1 beta
AttachmentSize
sendMailToMori.zip4.5 KB
Create Entry from Mail Message.scpt.zip4.2 KB

No need to define rule in the script.

I wrote a script yesterday, too, but it was my first time using AppleScript and so it took me until 2am and my eyes closed before I could prepare it for 'prime time' :)

One significant difference, though, which I think is worth using here is the outside of my script:

using terms from application "Mail"
----on perform mail action with messages theMessages
--------tell application "Mail"
------------repeat with eachMessage in theMessages
------------...
------------...
------------end repeat
--------end tell
----end perform mail action with messages
end using terms from

I like this because it applies the script to all messages that meet the rule, so you don't have to define the rule in Mail.app and the same 'rule' in your script.

-- Si Brindley

(I've had a copy of Getting Things Done on my desk for five months and I just got around to starting it.)

on perform mail action

I haven't used the "on perform mail action" call before, but I see that a lot of scripts involving Mail.app do. Does your script run automatically without the user invoking it or selecting messages? Does the script have to be running, or does it just reside somewhere that Mail will check upon receiving new messages?
The only drawback I can see is that even though the initial setup is easier (i.e. you don't have to set up a Mail rule,) I think your script runs whenever a new mail arrives regardless of whether it's tagged or not (and depending on when "on perform mail action" is called it might be run more often than that), and scripted checks are bound to be slower than the built in Cocoa checks of Mail rules. Of course, this may be avoided if you pre-compile the script as a run-only.
In the end, I'm not sure which method is going to be more optimal, but I welcome the discussion to improve the script.

The setup is the same as

The setup is the same as yours. You put the script wherever you like, and you create a rule in Mail.app that runs the script whenever a 'Subject contains [mori]'. The actions in the script are applied to the mail that triggered the rule (ones with 'mori' in the subject).

Ok

I like this because it applies the script to all messages that meet the rule, so you don't have to define the rule in Mail.app and the same 'rule' in your script.

Ok, I think I misunderstood your comment above. I thought that you were saying that because the script checked the 'rule', you didn't have to set a Mail rule. But, if I understand correctly now, it's the opposite: because the Mail rule already checks for the presence of the tag, the script doesn't have to recheck. So in that case I wouldn't need the line with "whose subject contains sendTag".

Is that correct? If so, your version would be more efficient because it doesn't go through the entire Inbox looking for matches. Thanks.

Yup, that's what I meant.

Here's my script. It's not as clever, is it doesn't remove the word 'mori' and it doesn't delete e-mails once the entry is created, but as a newbie I'm proud of it (it took me hours):

using terms from application "Mail"
  on perform mail action with messages theMessages
    set warned to "false"
    tell application "Mail"
      repeat with eachMessage in theMessages as list
        set entry_name to subject of eachMessage
        set entry_note to content of eachMessage
        tell application "Mori"
          tell front document
            if (exists entry named "Inbox" of entry named "Trash") and (warned = "false") then
              display dialog "Warning: You have an 'Inbox' entry in the Trash. New Inbox created."
              set warned to "true"
            else
              if (exists entry named "Inbox" of root entry) then
                set inbox_entry to entry named "Inbox" of root entry
              else
                set inbox_entry to make entry with properties {name:"Inbox", content type:"public.folder"}
                set index of inbox_entry to 0
              end if
              tell inbox_entry
                try
                  make new entry with properties {name:entry_name, note:entry_note}
                end try
              end tell
            end if
          end tell
        end tell
      end repeat
    end tell
  end perform mail action with messages
end using terms from

But it does have a 'safety' feature: with the sample script, if you've deleted your Inbox then items will be created in the Trash (where they probably won't be seen). So in my script, if it finds an "Inbox" in the trash it assumes you deleted it by mistake and warns you, created a new Inbox in the root.

I'd love to see my "on perform mail action" method and "test for deleted Inbox" features in the next version of your awesome script ;)

Are you sure that items will

Are you sure that items will be created in the trash? I just trashed my inbox and ran the script and I got a new inbox with the message from Mail inside (and nothing new inside the trash.) If I had to guess, your entries were probably created in the trash if you used: "set inbox_entry to entry named "Inbox"" and not "set inbox_entry to entry named "Inbox" of root entry". Without adding the "of root entry" the script found your inbox in the trash. (I'm just guessing here.)
Some people might want to trash their inbox when it's empty, so that they always know when something new and unprocessed has shown up.

Yes, there's multiple ways of working.

All this is true...and if you don't want to keep your Inbox in the root folder then you don't want one creating there for new entries just because you don't already have an "Inbox" off the root folder.

We're all trying to make scripts that suit our own way of working, but none of them is flexible enough (yet) to accommodate every way of working. So each of them needs customizing to suit the tastes of individual users, I think.

In my case, I keep my Inbox folder off the root. If I have accidentally moved the folder to the trash, I don't want it to be replaced without warning (which is what your script does) because then I'll think that the only items I need to know about are the new ones (and I'll forget about the existing items which are in the Inbox folder in the Trash). That is why my script tells me it found an Inbox in the Trash.

But that's just me :D

Stand up

(I've had a copy of Getting Things Done on my desk for five months and I just got around to starting it.)

Ba-da-doom. *Ching*. Thank ... you, thankyouverymuch. You've been a wonnaful, wonnaful audience. :)

Phil

Perfect!

This fits the bill 100%. *Thank you* BMEguy!

More Features

Here's one I wrote with several extra features. It acts as a script on a Mail rule and it gets the text to remove from the subject from the mail rule (it looks for what you put in the subject header rule condition if you have one; otherwise it just takes the subject as is), so you only need to configure things in one place. It also has an append feature so that if you send two notes with the same subject the second is appended to the first.

Still need to add support for putting the entry in an arbitrary folder. Let me know what you think.


property mailedEntryFolderName : "From Mail"
property subjectFlag : ""

using terms from application "Mail"
on perform mail action with messages theMessages for rule theRule
repeat with cond in theRule's rule conditions
if cond's rule type is subject header then set subjectFlag to expression of cond
end repeat
tell application "Mail"
repeat with thisMessage in theMessages
--get the subject and note
set _subject to subject of thisMessage
set _note to content of thisMessage

--strip the flag
set saveDelim to AppleScript's text item delimiters
set AppleScript's text item delimiters to {subjectFlag}
set theList to every text item of _subject
set AppleScript's text item delimiters to {""}
set _subject to theList as text
set AppleScript's text item delimiters to saveDelim

--add entry to Mori in folder named mailedEntryFolderName of root entry
tell application "Mori"
tell front document
--create folder for mailed entries if it doesn't exist
if not (exists entry named mailedEntryFolderName of root entry) then
make new entry with properties {name:"From Mail", content type:"public.folder"}
end if

--add new note, or append if there's already a note with that name
if (exists entry named _subject of entry named mailedEntryFolderName of root entry) then
set note of (entry named _subject of entry named mailedEntryFolderName of root entry) to note of (entry named _subject of entry named mailedEntryFolderName of root entry) & return & "----" & return & return & _note
else
set newEntry to make new entry at end of entries of (entry named mailedEntryFolderName of root entry) with properties {name:_subject, note:_note}
end if
end tell
end tell
end repeat
end tell
end perform mail action with messages
end using terms from

I'll include this in a near future release of Mori scripts I've written.

Looks good.

Looks good. I like that you only have to change the subject tag in one place (and not even the script, for people who don't feel comfortable firing up script editor.)
The only thing I'd change would be when you make the new folder in Mori to receive the mail, use your mailedEntryFolderName property rather than the static "From Mail" string.

Oops. On my way to

Oops. On my way to generality I forgot to generalize all the code.

Very nice! Although I

Very nice! Although I haven't tried your script I suspect it is going to suffer a similar gotcha to the one I tried to accommodate in mine: if you e-mail using a subject you've used before that you have deleted then your new content will be appended to a message that is in the Trash, which is probably not what you want :)

Yeah, I forgot about that.

Yeah, I forgot about that. I'll have to add that in the next release.

Whitespace

Hmmmm, if I'm not careful I get note titles which start with a space. Is there a way to trim whitepace in the "strip the flag" sequence? For now I'm setting my flag to "[Mori] " with a trailing space,

Phil

Send to mail

Here's a script that will send Mori entries to a new mail message. I'm just attaching the code to this thread for now because I plan to release several AppleScript scripts I've worked on in a package (I think I have enough scripts now, I just need to package it).


tell application "Mori"
tell front document
set selection_cover to selection

set d to make new entry
set d's name to "tmp" & ((current date) as string)

--copy notes into new entry's note
repeat with each_cover_entry in selection_cover as list
my assembled_content_for_entry(d, each_cover_entry)
end repeat

--make headings of entry titles in new entry
tell note of d
repeat with each in paragraphs
if first character of each is "+" then
delete first character of each
set size of each to 36
end if
end repeat
end tell
end tell

set myNote to d's note

tell application "Mail"
make new outgoing message with properties {content:myNote, subject:"Notes from Mori", visible:true}
end tell

delete d

end tell

on assembled_content_for_entry(d, each_entry)
tell application "Mori"
set d's note to (a reference to d's note) & return & "+" & each_entry's name & return & return & (a reference to each_entry's note) & return

--recurse down the tree
repeat with each in entries of each_entry
my assembled_content_for_entry(d, each)
end repeat
end tell
end assembled_content_for_entry

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.