Mostrando entradas con la etiqueta code snippets. Mostrar todas las entradas
Mostrando entradas con la etiqueta code snippets. Mostrar todas las entradas

martes, 8 de junio de 2010

Problema con StoneageHTML y cssutils

Si has llegado a este post por realizar una busqueda en tu buscador favorito, lo mas probable que sea porque te has topado con el mismo problema que me hizo renegar unas buenas horas. Y es ese el motivo por el cual agrego esta entrada a mi blog, quizas a alguien mas le ahorra un par de horas.


Time 2010/05/31 14:28:38.352 GMT-3
User Name (User Id) xxxxxxxx (xxxxxxxx)
Request URL
http://xxxxxxxxxxxxxxxx:8080/[…]/newsletter-stats.html
Exception Type AttributeError
Exception Value 'list' object attribute 'append' is read-only

Traceback (innermost last):

* Module ZPublisher.Publish, line 119, in publish
* Module ZPublisher.mapply, line 88, in mapply
* Module ZPublisher.Publish, line 42, in call_object
* Module plone.z3cform.layout, line 49, in __call__
* Module Shared.DC.Scripts.Bindings, line 313, in __call__
* Module Shared.DC.Scripts.Bindings, line 350, in _bindAndExec
* Module Products.PageTemplates.PageTemplateFile, line 129, in _exec
* Module Products.PageTemplates.PageTemplate, line 89, in pt_render
* Module zope.pagetemplate.pagetemplate, line 117, in pt_render
* Module zope.tal.talinterpreter, line 271, in __call__
* Module zope.tal.talinterpreter, line 346, in interpret
* Module zope.tal.talinterpreter, line 891, in do_useMacro
* Module zope.tal.talinterpreter, line 346, in interpret
* Module zope.tal.talinterpreter, line 536, in do_optTag_tal
* Module zope.tal.talinterpreter, line 521, in do_optTag
* Module zope.tal.talinterpreter, line 516, in no_tag
* Module zope.tal.talinterpreter, line 346, in interpret
* Module zope.tal.talinterpreter, line 891, in do_useMacro
* Module zope.tal.talinterpreter, line 346, in interpret
* Module zope.tal.talinterpreter, line 536, in do_optTag_tal
* Module zope.tal.talinterpreter, line 521, in do_optTag
* Module zope.tal.talinterpreter, line 516, in no_tag
* Module zope.tal.talinterpreter, line 346, in interpret
* Module zope.tal.talinterpreter, line 949, in do_defineSlot
* Module zope.tal.talinterpreter, line 346, in interpret
* Module zope.tal.talinterpreter, line 536, in do_optTag_tal
* Module zope.tal.talinterpreter, line 521, in do_optTag
* Module zope.tal.talinterpreter, line 516, in no_tag
* Module zope.tal.talinterpreter, line 346, in interpret
* Module zope.tal.talinterpreter, line 957, in do_defineSlot
* Module zope.tal.talinterpreter, line 346, in interpret
* Module zope.tal.talinterpreter, line 536, in do_optTag_tal
* Module zope.tal.talinterpreter, line 521, in do_optTag
* Module zope.tal.talinterpreter, line 516, in no_tag
* Module zope.tal.talinterpreter, line 346, in interpret
* Module zope.tal.talinterpreter, line 891, in do_useMacro
* Module zope.tal.talinterpreter, line 346, in interpret
* Module zope.tal.talinterpreter, line 957, in do_defineSlot
* Module zope.tal.talinterpreter, line 346, in interpret
* Module zope.tal.talinterpreter, line 536, in do_optTag_tal
* Module zope.tal.talinterpreter, line 521, in do_optTag
* Module zope.tal.talinterpreter, line 516, in no_tag
* Module zope.tal.talinterpreter, line 346, in interpret
* Module zope.tal.talinterpreter, line 534, in do_optTag_tal
* Module zope.tal.talinterpreter, line 516, in no_tag
* Module zope.tal.talinterpreter, line 346, in interpret
* Module zope.tal.talinterpreter, line 949, in do_defineSlot
* Module zope.tal.talinterpreter, line 346, in interpret
* Module zope.tal.talinterpreter, line 536, in do_optTag_tal
* Module zope.tal.talinterpreter, line 521, in do_optTag
* Module zope.tal.talinterpreter, line 516, in no_tag
* Module zope.tal.talinterpreter, line 346, in interpret
* Module zope.tal.talinterpreter, line 949, in do_defineSlot
* Module zope.tal.talinterpreter, line 346, in interpret
* Module zope.tal.talinterpreter, line 586, in do_setLocal_tal
* Module zope.tales.tales, line 696, in evaluate
URL: controlpanel
Line 10, Column 4
Expression: Names: {'container': , 'context': , 'default':

,

'here': ,
'loop': {},
'nothing': None,
'options': {'args': ()},
'repeat': ,
'request': URL=http://xxxxxxxxxxxxxxxx:8080/[…]/newsletter-stats.html>,
'root': ,
'template': ,
'traverse_subpath': [],
'user': ,
'view': ,
'views': 0xb0e04a8c>}

* Module zope.tales.expressions, line 217, in __call__
* Module Products.PageTemplates.Expressions, line 161, in _eval
* Module Products.PageTemplates.Expressions, line 123, in render
* Module plone.z3cform.layout, line 58, in contents
* Module plone.z3cform.layout, line 66, in render_form
* Module z3c.form.form, line 189, in __call__
* Module plone.z3cform.crud.crud, line 381, in update
* Module plone.z3cform.crud.crud, line 229, in update
* Module z3c.form.form, line 186, in update
* Module z3c.form.action, line 99, in execute
* Module z3c.form.button, line 302, in __call__
* Module z3c.form.button, line 170, in __call__
* Module collective.dancing.browser.stats, line 124, in handle_process_jobs
* Module collective.singing.async, line 22, in process
* Module collective.singing.async, line 37, in __call__
* Module collective.dancing.browser.sendnewsletter, line 51, in _assemble_messages
* Module collective.singing.scheduler, line 117, in __call__
* Module collective.singing.scheduler, line 109, in render_message
* Module collective.dancing.composer, line 307, in render
* Module plone.memoize.volatile, line 272, in replacement
* Module collective.dancing.composer, line 297, in _render
* Module stoneagehtml.stoneagehtml, line 91, in compactify
* Module stoneagehtml.stoneagehtml, line 208, in compactify
* Module cssutils.css.cssstylesheet, line 106, in _setCssRules

AttributeError: 'list' object attribute 'append' is read-only

Bien, ahora, a que se debe esto ? bueno, basicamente, en las ultimas versiones del producto cssutils[0] (yo me tope con el problema en la version 0.9.7a4) en el archivo cssutils/css/cssstylesheet.py linea 104, se sobre-escribe el metodo setter del campo cssRules (atributo de la clase), en donde se intenta reemplazar el metodo 'append' de cssRules (parametro de entrada del metodo).

El problema radica, cuando en lugar de que cssRules (parametro del metodo) sea un cssutils.css.CSSRuleList, sea una lista (tipo built-in de python), lo que provoca que dicha excepcion se levante.

Esto ultimo, es provocado por la linea 208 del archivo stoneagehtml/stoneagehtml.py del producto StoneageHTML[1]:

sheet.cssRules = self.filterCSSDeclarations(sheet.cssRules)

ya que filterCSSDeclarations devuelve una lista (la cual se pasa al setter del cssRules, provocando el crash descripto arriba).

La solucion, seria que stoneageHTML se actualizara, para funcionar con las ultimas versiones de cssutils, pero al momento de escribir esto, dicha solcion no existe, con lo cual la siguiente solucion es hacer un downgrade de cssutils. En mi caso, lo hice a la 0.9.5 ya que es la que en fechas esta mas cerca del lanzamiento de stoneageHTML 0.1.5, luego de lo cual, el crash desaparecio y todo funciona bien de nuevo.

Ya me puse en contacto con el desarrollador de StoneageHTML para informarle de este bug, y ver si puede especificar la dependencia de cssutils para que su producto funcione, o que en su defecto saque una version mas nueva de StoneageHTML. Tratare de actualizar la entrada con la informacion que obtenga de el.

[0] - http://pypi.python.org/pypi/cssutils
[1] - http://pypi.python.org/pypi/StoneageHTML

lunes, 11 de mayo de 2009

Customizando una portal tool

Cuando se trabaja en sitios Plone, a menudo se trabaja desde la interfaz ZMI (Zope Management Interface). Por consiguiente, a veces es necesario cambiar el funcionamiento de alguna de estas 'tools' que fueron provistas por algun producto.
Yo voy a mostrarlo tomando como ejemplo la tool provista por el producto que integra Plone con Salesforce, Product.salesforcebaseconnector.
Aqui como:

1) Agregar un archivo toolset.xml a nuestro profile/default (o el profile que esten usando) con lo siguiente

<?xml version="1.0"?>
<tool-setup>
<required tool_id="portal_salesforcebaseconnector"
class="salesforce.patch.salesforcebaseconnector.SalesforcePatched"/>
</tool-setup>
2) En un archivo python (salesforcebaseconnector) lo siguiente:

from Products.salesforcebaseconnector.salesforcebaseconnector import SalesforceBaseConnector
from Products.PageTemplates.PageTemplateFile import PageTemplateFile

from AccessControl import ClassSecurityInfo
from Products.CMFCore.permissions import ManagePortal


class SalesforcePatched(SalesforceBaseConnector):

def __init__(self):
super(SalesforcePatched, self).__init__()

security = ClassSecurityInfo()
security.declareProtected(ManagePortal, 'manage_config')

manage_config = PageTemplateFile('www/manageAuthConfigCustom', globals() )

3) Por ultimo en la carpeta www, un manageAuthConfigCustom.zpt con el template customizado

4) Instalar el producto y la tool se reeinstalara (cuidado aca, si habia datos que la tool mantenia, como en este caso el login a salesforce, todo eso se pierde, y hay que volver a cargarlos)

En realidad, en la clase SalesforcePatched piso un par de metodos de SalesforceBaseConnector, que no vienen al caso ahora.

Espero que a alguien le sirva esto.

Cheers

EDIT: Gracias Santiago por el comentario para poder meter codigo xml en el post y para colorear, aguante Kate :D

jueves, 26 de marzo de 2009

Creando usuarios programaticamente en Plone


from Products.CMFCore.utils import getToolByName
#Primero pedimos la portal_registration tool
pr = getToolByName(context, 'portal_registration')
id = 'id_usuario'
password = 'password'
#En este diccionario cargamos campos adicionales
props = {
'username' : id,
'fullname' : 'Nombre Completo',
'email' : 'email_del_usuario',
}

pr.addMember(id, password, properties=props)


API: http://api.plone.org/CMF/2.1.0/public/frames/products/CMFCore/products.CMFCore.MembershipTool.MembershipTool-class.html#addMember