Documention for: do-pop-scheme.r Created by: brett on: 10-Jul-2005 Last updated by: brett on: 24-Jul-2005 Format: text/editable Downloaded on: 29-Mar-2024 DO-POP Scheme See the Copyright and Terms at the bottom of this page if you want to use the DO-POP-SCHEME.r script. ===What is it? The Do-pop scheme is a way to control a POP mailbox using REBOL functions. ===Why is it useful? ---Access to more POP commands The built-in REBOL POP Scheme makes accessing a POP mailbox easy using normal series functions, but it does not make all features of POP3 available. For example, people often want to use the TOP command to get just the headers of an email without downloading the whole message. Another example is the requirement to get a unique id listing (UIDL) to implement a "leave on server" option. ---Nice syntax for complicated POP mailbox scripts. The Do-pop scheme provides all POP3 commands using a function based API which makes it easy to mix POP3 operations with other REBOL code. It does this by making some specific words have special meaning within the context of a POP3 transaction state. ===How do you use it? You specify a username, password and server in the same way as you would for using the built-in POP scheme. ---One liner operation Just doing a Read on the mailbox gives you the mailbox statistics. For example, to get the statistics of the mailbox in one operation: read: do-pop://username:password@mail.codeconscious.com ---Port based operation Normally, for this scheme you would open a port so that you can carry out a number of POP operations without logging in more than once. The port evaluates the values you give it. You insert REBOL values into the Port, the values are evaluated by the scheme and you copy the result back out. It is easiest to define a helper function to do this so that you can use it as easily as you use the REBOL DO function. Some specific words (see the list below) are evaluated within the context of the scheme - ie they are rebound. For example, inserting the word 'List into the port will evaluate to a the list of messages in the mailbox. Here's an example that shows opening the port, defining the helper function and how REBOL code can be easily mixed with POP operations. It prints the ordinal message number and subject for all the emails in a mailbox: pop-service: open do-pop://mailbox:password@mailserver.com do-pop: func [value][insert pop-service value copy pop-service] foreach [msgnum size] do-pop 'list [ do-pop [ print [msgnum get in import-email top msgnum 'subject ] ] ] close pop-service \note Use the console and help Using the helper function makes it easy to test your ideas at the console prompt and because the words are context specific you can use the REBOL help function: do-pop [help uidl] /note ===What are the context specific words? ---Operations \table Function Usage Description =row DELE message-number Marks the message as deleted. Affects STAT, LIST, UIDL. =row NOOP Sends the noop command. =row LIST /only message-number Returns scan listings of messages. =row RETR message-number Retrieves the message. =row RSET Unmarks (resets) all messages marked as deleted. =row STAT Returns statistics of mailbox as [length size]. =row TOP message-number /lines number Returns headers for message. =row UIDL /only message-number Returns unique-id listing. /table ---Variables \table Variable Description =row mailbox-length The number of messages in the mailbox when it was opened. =row mailbox-size The size of the mailbox in bytes. =row pop-result The last result returned by an operation. /table ===Operation of POP and statistics POP assigns ordinal numbers to the messages in the mailbox which do not change for the duration of the session. However, you cannot assume that the ordinal numbers will be the same in a different POP session. DELE *marks* messages for deletion but they are not physically deleted by the server until after QUIT is issued. Messages can be unmarked with RSET. For this reason the the mailbox-length and mailbox-size variables are not updated for DELE and keep their original values from when the port is opened. Messages marked for deletion do not appear in the results for LIST, UIDL and STAT, and you cannot retrieve them using RETR. At any given time, the number of messages that will be left after all messages marked for deletion have been removed will be: (mailbox-length - messages-deleted) \note Keeping statistics When the port is closed the variables are destroyed, so if you want to keep the statistics make a copy of them before closing the port. /note This scheme issues a QUIT to the POP server when the port is closed. ===Why use a scheme? I designed the solution with a scheme because a REBOL port will automatically receive a close event when REBOL shuts down even if the script that opened the port does not forgets/cannot issue the close. In terms of POP, that allows me to gracefully issue a QUIT to the server before the connection is closed. ===Are some of the ideas taken from REBOL's service oriented architecture? No, but I admit there are ideas in the do-pop-scheme which are exceptionally close to concepts in REBOL service oriented architecture. At the time of writing REBOL's service oriented architecture has not been released however documents describing it have been published. I arrived at the design of the do-pop-scheme through a process that evolved the solution through two other designs that did not involve a scheme and without having the REBOL service oriented architecture in mind. For me, the process was the point of the excercise not the do-pop-scheme. For my purposes, POP was a convient case study. Now when reading about REBOL's service oriented architecture, after having developed the do-pop-scheme, I am glad there are correspondences. The process had made me feel confident that the REBOL service oriented architecture will be very valuable when it is released. ===Copyright and Terms for DO-POP-SCHEME.r and this document Copyright (C) 2005 Brett Handley All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ===About the script author Brett Handley started programming REBOL early 2000 and maintains a site of REBOL information and scripts at http://www.codeconscious.com