REBOL [
    Title: "Check POP mail"
    Date: 21-Aug-2002
    Name: POP-check
    Version: 1.0.0
    File: %POPCHECK.R
    Home: http://www.ci.bloomington.mn.us
    Author: "Steven White"
    Owner: "City of Bloomington MN"
    Rights: "Copyright (C) City of Bloomington 2002"
    Tabs: 4
    Purpose: {Checks email messages in a POP account and reports
relevant information to another email address.
   }
    Comment: "^/    "
    History: [
]
    Language: English
    Email: swhite@ci.bloomington.mn.us
    Category: [email]
    Need: 2.3
    Example: "do popcheck.r or run from a script"
]

; [------------------------------------------------------------------]
; [ The following items customize this script for its actual user.   ]
; [ Change them to match your own mail server, user name,            ]
; [ password, and so on.                                             ]
; [                                                                  ]
; [ MY-POP-USERID     This is the user name you picked when setting  ]
; [                   up the account with the ISP.  This should be   ]
; [                   a string, that is, in double quotes.           ]
; [ MY-POP-PASSWORD   This is the password you selected when setting ]
; [                   up the email account.  This should be a string.]
; [ MY-POP-SERVER     Your ISP has a server (computer) that handles  ]
; [                   email going out, and that computer has a name. ]
; [                   You will have to call them and ask them what   ]
; [                   the name is.  Enter it here as a string        ]
; [                   because later on we will assemble it into a    ]
; [                   full internet URL.                             ]
; [ MY-NOTIFY-ADDRESS This is an email address to which this script  ]
; [                   will send a report of its findings.            ]
; [                   Enter this as an email address (not a string). ]
; [ MY-FRIENDS-LIST   This is a block of email addresses.  The       ]
; [                   script will check the from-addresses on the    ]
; [                   emails that it scans to see if they are        ]
; [                   addresses in this block.  If they are, then    ]
; [                   those messages will be counted as personal     ]
; [                   messages.                                      ]
; [                                                                  ]
; [ NOTE:  The data items below are junk put in to illustrate how    ]
; [ to use this script.  You will have to replace what you see       ]
; [ below with real data or the script will not work.                ]
; [ This should be the ONLY area that you will have to modify.       ]
; [------------------------------------------------------------------]

 MY-POP-USERID:     "myuserid"
 MY-POP-PASSWORD:   "mypassword"
 MY-POP-SERVER:     "pop.my-isp.net"
 MY-NOTIFY-ADDRESS: myname@myoffice.com
 MY-FRIENDS-LIST:   [friend1@isp1.com
                     friend2@isp2.com   
                    ]

; [------------------------------------------------------------------]
; [ These are some items we will want to make a note of early in     ]
; [ the program and refer to again later in the program.             ]
; [ Data items in REBOL are self-defining, that is, you don't have   ]
; [ to declare them in advance of using them as you do in other      ]
; [ programming languages.  However, you may declare them in some    ]
; [ way, such as by setting them to some initial values, if you      ]
; [ want to.  Some people who are used to the requirement of         ]
; [ declaring variables are comforted by having all variables        ]
; [ laid out beforehand.                                             ]
; [                                                                  ]
; [ TOTAL-MESSAGE-COUNT    As we scan the messages on the POP        ]
; [                        server, we will count them all.  This is  ]
; [                        as much a debugging tool as useful data.  ]
; [ PERSONAL-MESSAGE-COUNT Messages with a "from" field matching     ]
; [                        a known personal address will be counted  ]
; [                        in this word as personal messages.        ]
; [------------------------------------------------------------------]

 TOTAL-MESSAGE-COUNT: 0
 PERSONAL-MESSAGE-COUNT: 0

; [------------------------------------------------------------------]
; [ Print a beginning-of-job message to reassure that we             ]
; [ are running.  We will clear the screen first as a                ]
; [ cosmetic touch.                                                  ]
; [ The "prin" command is the same as "print" but does not return    ]
; [ the cursor to the next line.                                     ]
; [ The ^ is used to indicate a special control character.           ]
; [ The (page) indicates the control character that causes,          ]
; [ on this particular computer (meaning the computer on which       ]
; [ you are running the script), the screen to get blanked.          ]
; [------------------------------------------------------------------]

 prin "^(page)"
 print ["Checking email from" MY-POP-SERVER]

; [------------------------------------------------------------------]
; [ Assemble this particular script's user ID, password, and POP     ]
; [ server name into a full URL so we can read email.                ]
; [ We use the "join" command to concatenate together a bunch of     ]
; [ strings that will read like a URL, but then to make that         ]
; [ concatenated bunch of strings into a URL in whatever internal    ]
; [ format REBOL keeps URL's, we have to apply the "to-url"          ]
; [ function to that string.                                         ]
; [------------------------------------------------------------------]

 POP-URL-STRING: join "pop://"  
     [MY-POP-USERID ":" MY-POP-PASSWORD "@" MY-POP-SERVER]
 POP-URL: to-url POP-URL-STRING

; [------------------------------------------------------------------]
; [ Get all email messages from our POP server and                   ]
; [ store them in a block of strings, with each string               ]
; [ being one email message.                                         ]
; [ Print the number of messages to indicate we are done.            ]
; [------------------------------------------------------------------]

 ALL-MAIL: read POP-URL
 TOTAL-MESSAGE-COUNT: length? ALL-MAIL
 print [TOTAL-MESSAGE-COUNT "messages from" MY-POP-SERVER]

; [------------------------------------------------------------------]
; [ Make another block which will contain                            ]
; [ all the scanned messages decoded into a recognizable             ]
; [ form.                                                            ]
; [------------------------------------------------------------------]

 SCANNED-MESSAGES: []

; [------------------------------------------------------------------]
; [ Go through the block of mail and decode each message             ]
; [ into a block of scanned messages.                                ]
; [ As we append messages to the SCANNED-MESSAGES block, the size    ]
; [ of that block will increase by one with each pass through the    ]
; [ "foreach" loop.  We will use that ever-increasing length as      ]
; [ a counter of messages we have read, and display it as a          ]
; [ confirmation that the script is running.  This display could     ]
; [ be taken out if you wanted the script to run more "quietly."     ]
; [------------------------------------------------------------------]

 foreach NEXT-MESSAGE ALL-MAIL [
     append SCANNED-MESSAGES import-email NEXT-MESSAGE
     print ["Message" length? SCANNED-MESSAGES "scanned"]
 ]

; [------------------------------------------------------------------]
; [ Set up a canned email message that we will tailor with           ]
; [ information about the email messages we scan below.              ]
; [ NOTIFY-MESSAGE must be one big string if we are to send it       ]
; [ as an email message.  If we want the message to look nice to     ]
; [ the recipient, we will put in some line-feeds to separate the    ]
; [ lines.  This is done with the "^/" characters, which are the     ]
; [ coding REBOL recognizes as a string that consists of the         ]
; [ line-feed character.                                             ]
; [ Notice also that we are joining strings together, so we use      ]
; [ the "to-string" function to convert TOTAL-MESSAGE-COUNT to a     ]
; [ a string.                                                        ]
; [ Remember now that we are just setting up the message here.       ]
; [ The next step will be to append to this string, that we are      ]
; [ just setting up, a summary line for each personal email          ]
; [ message.                                                         ]
; [------------------------------------------------------------------]

 NOTIFY-MESSAGE: join "Email summary from " [
     MY-POP-SERVER
     "^/"
     "You have "
     to-string TOTAL-MESSAGE-COUNT
     " messages total messages including the following personal ones."
     "^/"
     ]

; [------------------------------------------------------------------]
; [ Finally, look at each scanned message and report who             ]
; [ sent it.  This also could be commented out if you wanted         ]
; [ the script to run quietly.                                       ]
; [ In addition, as long as we are going through the block of        ]
; [ SCANNED-MESSAGES, check the "from" field against each address    ]
; [ in the block of known friends in MY-FRIENDS-LIST.  If the "from" ]
; [ field does match some known address, increase the count of       ]
; [ personal messages and string together a summary of who this      ]
; [ message is from and what it is about.  Append this summary to    ]
; [ the NOTIFY-MESSAGE that we initialized earlier and will send     ]
; [ out later.                                                       ]
; [                                                                  ]
; [ The "if" statement below is an example of how a single line of   ]
; [ code can be very hard to understand for someone not familiar     ]
; [ with REBOL.  The "if" statement causes the following block of    ]
; [ code to be "executed" IF the condition is NOT FALSE--OR, not     ]
; [ NONE.  The "find" function returns the block you are "finding"   ]
; [ something in if you have found something, but if you don't       ]
; [ find anything, it returns NONE.                                  ]
; [                                                                  ]
; [ The "find" function needs a block to find something in, and then ]
; [ it returns that block repositioned to the place where something  ]
; [ was found.  On subsequent passes through the loop, we would      ]
; [ "find" from that new position if we didn't reposition the block  ]
; [ at the beginning each time with the "head" function.             ]
; [                                                                  ]
; [ This is an example of how REBOL works.  The "head" function      ]
; [ feeds something into the "find" function which feeds something   ]
; [ into the "if" function.  These can get quite involved.           ]
; [------------------------------------------------------------------]

 foreach CURRENT-MSG SCANNED-MESSAGES [
     prin  ["From:" CURRENT-MSG/from]
     prin  " "
     print ["SubJect:" CURRENT-MSG/subject] 
     if find head MY-FRIENDS-LIST CURRENT-MSG/from [
         PERSONAL-MESSAGE-COUNT: ADD PERSONAL-MESSAGE-COUNT 1
         append NOTIFY-MESSAGE join  
             "From: " [
                 CURRENT-MSG/from
                 " "
                 "Subject: "
                 CURRENT-MSG/subject 
                 "^/"
                 ]
     ]
 ]

; [------------------------------------------------------------------]
; [ Print an end-of-job message just because we like to              ]
; [ assure the operator that things are progressing.                 ]
; [------------------------------------------------------------------]

 print "Done checking email"
 print [PERSONAL-MESSAGE-COUNT "Personal messages"]
 print ["We will send the following message to "
         to-string MY-NOTIFY-ADDRESS]
 print NOTIFY-MESSAGE

; [------------------------------------------------------------------]
; [ Send out the message we have built up.                           ]
; [------------------------------------------------------------------]

 send MY-NOTIFY-ADDRESS NOTIFY-MESSAGE

; [------------------------------------------------------------------]
; [ And, quit (the default operation if we "run off the end."        ]
; [------------------------------------------------------------------]

 halt