[Zope] Re: Cron & Receiving email

Chris McDonough chrism@digicool.com
Wed, 16 May 2001 09:58:32 -0400


This is a multi-part message in MIME format.

------=_NextPart_000_0076_01C0DDEE.C403EB40
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

> 1) Is there a cron-like tool in Zope? Or a way to have cron
> run a process in Zope?

Zope is completely event-driven, so there's no scheduler built in to it.

There's a product named Xron which provides cron-like functionality within
Zope (I've not used it).

You can also use a Python script (a real one, on disk, having nothing to do
with Zope) that calls a Zope method via HTTP or XML-RPC.  Attached is a
module named XMLRPCBasicAuth.py, which you can use like this:

>>> import XMLRPCBasicAuth
>>> s = XMLRPCBasicAuth.Server('http://www.zope.org','chrism', 'mypassword')
>>> s.Members.chrism.manage_addDocument('foo', 'bar', 'some text')

Note that the library named "xmlrpclib" needs to be somewhere in your
PYTHONPATH (read the source of the XMLRPCBasicAuth.py file to see how to put
it in).  Also, you'll likely see things like "ProtocolErrors" and HTML being
returned from XMLRPC method calls.  You'll need to experiment with what you
want to to (e.g. use the XMLRPCBasicAuth module to call methods from a
Python prompt, and then take a look at the running Zope via the Zope web
mgmt interface after you've made a call to see if the call has succeeded,
and its results), but for the most part, you can just call methods on Zope
objects like you would if you were at a Python prompt, the two notable
exceptions being:

1.  You can't pass keyword arguments.
2.  XMLRPC can only marshal certain types, and object instances aren't one
of them.

Combining a Python program that uses XMLRPC with UNIX cron (or WinNT
Scheduler service) allows you to kick off events at scheduled times.

>
> 2) Under Linux/Sendmail, can I have the above Zope process
> "receive" mail sent to a particular address? (Note that my
> ignorance of how mail works could fill volumes).

Not really.  If you can expland on what you'd like to accomplish by doing
this, maybe I can help a little better.

- C


------=_NextPart_000_0076_01C0DDEE.C403EB40
Content-Type: text/plain;
	name="XMLRPCBasicAuth.py"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename="XMLRPCBasicAuth.py"

import sys

# change this line to point to somewhere where xmlrpclib can be
# imported from!
sys.path.insert(0, '/home/chrism/sandboxes/2_3Branch/lib/python')
import xmlrpclib
import base64
import string

def Server(url, username, password):
    t = BasicAuthTransport(username, password)
    return xmlrpclib.Server(url, t)

class BasicAuthTransport(xmlrpclib.Transport):
    """Handles an HTTP transaction to an XML-RPC server with basicauth """
    
    def __init__(self, username, password):
        self.username = username
        self.password = password

    def request(self, host, handler, request_body):
        # issue XML-RPC request

        username = self.username
        password = self.password
        
        import httplib
        h = httplib.HTTP(host)
        h.putrequest("POST", handler)

        # required by HTTP/1.1
        h.putheader("Host", host)

        # required by XML-RPC
        h.putheader("User-Agent", self.user_agent)
        h.putheader("Content-Type", "text/xml")
        h.putheader("Content-Length", str(len(request_body)))

        # basic auth
        if username and password:
            h.putheader("AUTHORIZATION", "Basic %s" % string.replace(
                base64.encodestring("%s:%s" % (username, password)),
                "\012", ""))

        h.endheaders()
        
        if request_body:
            h.send(request_body)

        errcode, errmsg, headers = h.getreply()

        if errcode != 200:
            raise ProtocolError(
                host + handler,
                errcode, errmsg,
                headers
                )

        return self.parse_response(h.getfile())


def test():
    s = Server('http://serenade.digicool.com:8083/', 'user1', 'mypass')
    print s.testmethod()

if __name__ == '__main__':
    test()

------=_NextPart_000_0076_01C0DDEE.C403EB40--