Sobrecargar la gestion del WebDAV/FTP
Mecanismo de añadido de objetos (en los contenedores)
Es necesario sobrecargar la funcion PUT_factory
Esta funcion se adquiere en el momento de la ejecucion, por tanto, si esta disponible en el punto donde se va a añadir objetos se ejecutara. Para que esta funcion se ejecute en todo vuestro site no teneis mas que crear un metodo externo con esta funcion y listos (supongo que tambien valdria con un script python pero no lo he testado, quizas alguien pueda completar esta info)
Os paso un ejemplo sencillo de PUT_factory:
from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
def PUT_factory(self, name, typ, body):
"""PUT_factory"""
partes = string.split(name, ".")
ext = partes[-1]
if ext in ["zpt", "pt", "htm", "html"]:
ob = ZopePageTemplate(name, body, content_type=typ)
else:
ob = None
return ob
Es importante que os deis cuenta de un par de detalles:
1.- Solo hay que sobrecargar los tipos que necesiteis. El resto de objetos se crean con el PUT_factory por defecto al devolver None (cuando no satisfacen ninguna de las sentencias del if2.- Es IMPRESCINDIBLE que el objeto creado (y devuelto en la funcion PUT_factory) tenga un metodo PUT puesto que este se ejecutara despues de PUT_factory. Si no lo tiene los servicios WebDAV/FTP daran un error (a veces un 500 otras un 426 creo)
Creacion de un objeto contenedor distinto de Folder al crear una carpeta via WebDAV/FTP
Este es sencillo, simplemente teneis que añadir en vuestro contenedor a partir del cual ya no se crearan folders si no vuestro propio contenedor la linea:
MKCOL_handler = manage_addFolder = manage_addDeVuestroProducto
Nota: por una inconsistencia en el codigo MKCOL_handler no funciona en el FTP de hay a poner manage_addFolder que es la funcion que se ejecuta via FTP. Para toda la gestion de FTP hay funciones tipo manage_addFolder (que luego veremos)
Creacion de un objeto no contenedor que se comporte bien en el WebDAV/FTP
Si necesitamos poner una imagen via WebDAV/FTP no habra problema puesto que este producto cumple con todas las especificaciones para estos protocolos. En cambio si quereis crear un producto propio y quereis seguir estas especificaciones debereis cumplir con los siguientes requisitos:
Importar
from webdav.Lockable import ResourceLockedError from webdav.WriteLockInterface import WriteLockInterface
Para el bloqueo WebDAV
En la definicion de la clase añadir
__implements__ = (WriteLockInterface,)
para que vuestro objeto implemente la interface de bloqueo de escritura
En la funcion de edicion del producto añadir estas lineas al principio del metodo
if self.wl_isLocked():
raise ResourceLockedError, 'Este NOMBREDELPRODUCTOPOREJEMPLO esta siendo editado por otro usuario'
Esto comprueba que el objeto no este bloqueado y si lo esta lanza el mensaje de error que indiqueis
Añadir esta funcion
def manage_FTPget(self):
"""Devuelve el estado por FTP. Codigo necesario para el soporte FTP"""
self.REQUEST.RESPONSE.setHeader('Content-Type', "text/plain")
return self.readState()
Esta funcion se ejecutara cuando se intente obtener el fichero via WebDAV/FTP. La funcion self.writeState() simplemente retorna un string (o lo que querais devolver) que corresponde con el contenido de que tendra el objeto. Por ejemplo si yo añado a mi producto esta funcion:
def writeState(self, Data):
"""Setea el estado del objeto dado un string. Codigo necesario para el soporte FTP"""
self.rawdata = Data
Al intentar abrir un objeto con estas fuciones encontraremos un fichero de texto (content-type -> text/plain) con el contenido en rawdata
Añadir esta funcion
def PUT(self, REQUEST, RESPONSE):
"""Handle HTTP PUT requests. Codigo necesario para el soporte FTP"""
self.dav__init(REQUEST, RESPONSE)
self.dav__simpleifhandler(REQUEST, RESPONSE, refresh=1)
self.writeState(REQUEST.get("BODY", ""))
RESPONSE.setStatus(204)
return RESPONSE
Como os indique antes, despues de ejecutarse la funcion PUT_factory del contenedor se ejecuta la funcion PUT del objeto a poner
En este caso la funcion hace:
1.- Bloquear el objeto via WebDAV
2.- ejecuta la funcion readState con el contenido de BODY de request
3.- retorna un codigo 204 indicando que todo ha ido bien
Yo no hago control de errores en este punto pero seguro que se pueden hacer maravillas (a mi el error que daria una excepcion ya me sirve de momento)
la funcion readState tendria un aspecto como este mas o menos
def readState(self):
"""Devuelve el estado del objeto como un string. Codigo necesario para el soporte de FTP"""
return self.rawdata
en este caso mi objeto tiene una propiedad llamada rawdata en el que se guarda el contenido del fichero
Por el momento y con este codigo a mi me esta funcionando estupendamente todo este proceso (despues de mi pelea con el Zope/Python, claro)
Tengo que darle las gracias a los que me han echao una mano con esto (este documento es tan vuestro como mio)
Santi Camps
Chris McDonough
A dia de hoy 26-02-2004 y con la version 2.7.0 de Zope funciona perfectamente
Os dejo a vuestro criterio totalmente el que useis el texto de este mensaje como mejor os plazca (eso si, os agradeceria que me enviaseis un link si lo poneis en vuestras webs/weblogs/oloquesea o que me envieis una copia si lo modificais, mas que nada para aprender de vosotros)
Saludos