Welcome | Members | News | Search | Documentacion | Foros |
You are here: Home » Miembros » Garito's Home » Sobrecargar la gestion del WebDAV/FTP
 
You are not logged in
Link icon Log in Link icon Join
Log in
Name
Password

Sobrecargar la gestion del WebDAV/FTP

Pasos necesarios para sobrecargar la gestion del WebDAV/FTP en tus productos

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 if
2.- 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)

Andres Moya
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