<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-277432651694323775</id><updated>2011-07-07T14:35:55.537-07:00</updated><title type='text'>Srikanth Suri's Blog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://srikanth-suri.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/277432651694323775/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://srikanth-suri.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Srikanth.T</name><uri>http://www.blogger.com/profile/06764094427574143045</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>4</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-277432651694323775.post-9086502612403861963</id><published>2010-04-28T21:38:00.000-07:00</published><updated>2010-04-28T22:11:27.918-07:00</updated><title type='text'>Leave management System  - An Open Source Contribution from Mahiti Infotech Bangalore</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://mahiti.org/portal_css/images/mahiti-logo.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 240px; height: 125px;" src="http://mahiti.org/portal_css/images/mahiti-logo.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;Hi All&lt;br /&gt;&lt;br /&gt;We have developed an application using &lt;span style="font-weight:bold;"&gt;Repoze.BFG&lt;/span&gt; and &lt;span style="font-weight:bold;"&gt;KARL&lt;/span&gt; as basis. The application, is named as &lt;span style="font-weight:bold;"&gt;LMS&lt;/span&gt;( &lt;span style="font-weight:bold;"&gt;Leave management System&lt;/span&gt; ). We want to contribute this project for &lt;span style="font-weight:bold;"&gt;Open Source Community&lt;/span&gt;.  We wish , &lt;span style="font-weight:bold;"&gt;LMS&lt;/span&gt; can act as a reference , for any one who is interested in learning KARL based repoze applications. &lt;br /&gt;Link to download, source code is : &lt;a href="https://sourceforge.net/projects/mahiti-lms"&gt;https://sourceforge.net/projects/mahiti-lms&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;Please feel free to tell us how it is and our lackings if any.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Srikanth.T&lt;/span&gt;&lt;br /&gt;Senior Programmer&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Sowmya.MK&lt;/span&gt;&lt;br /&gt;Team Lead&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Sreekanth S Rameshaiah&lt;/span&gt;&lt;br /&gt;CEO&lt;br /&gt;Mahiti Infotech Pvt. Ltd.&lt;br /&gt;# 33-34, 2nd Floor,&lt;br /&gt;Hennur Cross, Hennur Road,&lt;br /&gt;Bangalore, India - 560043&lt;br /&gt;Phone:  +91 80 4115 0580/1&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/277432651694323775-9086502612403861963?l=srikanth-suri.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://srikanth-suri.blogspot.com/feeds/9086502612403861963/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://srikanth-suri.blogspot.com/2010/04/leave-management-system-open-source.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/277432651694323775/posts/default/9086502612403861963'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/277432651694323775/posts/default/9086502612403861963'/><link rel='alternate' type='text/html' href='http://srikanth-suri.blogspot.com/2010/04/leave-management-system-open-source.html' title='Leave management System  - An Open Source Contribution from Mahiti Infotech Bangalore'/><author><name>Srikanth.T</name><uri>http://www.blogger.com/profile/06764094427574143045</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-277432651694323775.post-1541511535903626656</id><published>2010-02-14T23:27:00.000-08:00</published><updated>2010-02-15T04:44:05.516-08:00</updated><title type='text'></title><content type='html'>&lt;b&gt;How to create  Workflow for a repoze.BFG application&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Let us see , how we can create a workflow for a bfg application.&lt;br /&gt;&lt;br /&gt;To add a workflow add a file named workflow.py at the root of your site. you can name it as you like.&lt;br /&gt;Add methods related to the states and transitions as per your requirement.&lt;br /&gt;&lt;br /&gt;For Example, the following files does the work.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;workflow.py&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;table class="zeroBorder" border="0" cellpadding="12" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#d0d0ff"&gt;from repoze.bfg.security import Allow&lt;br /&gt;from repoze.bfg.security import Deny&lt;br /&gt;from repoze.bfg.security import Everyone&lt;br /&gt;from repoze.bfg.traversal import find_interface&lt;br /&gt;from repoze.bfg.traversal import model_path&lt;br /&gt;&lt;br /&gt;from project.security_policies.policy import ADMINISTRATOR_PERMS&lt;br /&gt;from project.security_policies.policy import GUEST_PERMS&lt;br /&gt;from project.security_policies.policy import MODERATOR_PERMS&lt;br /&gt;from project.security_policies.policy import MEMBER_PERMS&lt;br /&gt;from project.security_policies.policy import CREATE&lt;br /&gt;from project.security_policies.policy import NO_INHERIT&lt;br /&gt;from project.security_policies.workflow import postorder&lt;br /&gt;from project.security_policies.workflow import acl_diff&lt;br /&gt;from project.security_policies.workflow import reset_security_workflow&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;def find_showEvent(context):  &lt;br /&gt;&lt;span style="padding-left:26px"&gt;return find_interface(context, IshowEvent)&lt;br /&gt;&lt;br /&gt;def ts(*args):&lt;br /&gt;&lt;span style="padding-left:26px"&gt;return '\t'.join([str(x) for x in args])&lt;br /&gt;&lt;br /&gt;&lt;table class="zeroBorder" width="100%" bgcolor="#d0f0ff" border="0" cellpadding="2" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;#------------------------------------------------------------------------------&lt;br /&gt;#   Electors&lt;br /&gt;#------------------------------------------------------------------------------&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;def not_intranets_containment(context):&lt;br /&gt;&lt;span style="padding-left:26px"&gt;return not intranets_containment(context)&lt;br /&gt;&lt;br /&gt;def intranets_containment(context):&lt;br /&gt;&lt;span style="padding-left:26px"&gt;return False&lt;br /&gt;&lt;br /&gt;def private_showEvent_containment(context):&lt;br /&gt;&lt;span style="padding-left:26px"&gt;if not_intranets_containment(context):&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:52px"&gt;showEvent = find_showEvent(context)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:52px"&gt;if showEvent is None:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:78px"&gt;return False&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:52px"&gt;return getattr(showEvent, 'seproject.security_policies.policycurity_state', None) == 'private'&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;return False&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;def public_showEvent_containment(context):&lt;br /&gt;&lt;span style="padding-left:26px"&gt;if not_intranets_containment(context):&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:52px"&gt;showEvent = find_showEvent(context)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:52px"&gt;if showEvent is None:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:78px"&gt;return False&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:52px"&gt;return getattr(showEvent, 'security_state', None) == 'public'&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;return False&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;table class="zeroBorder" width="100%" bgcolor="#d0f0ff" border="0" cellpadding="2" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;#------------------------------------------------------------------------------&lt;br /&gt;#   Workflow for showEvent&lt;br /&gt;#------------------------------------------------------------------------------&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;def showEvent_to_private(ob, info):&lt;br /&gt;&lt;span style="padding-left:26px"&gt;showEvent = find_showEvent(ob)&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;acl = []&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;moderators_group_name = showEvent.moderators_group_name&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;members_group_name = showEvent.members_group_name&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;acl.append((Allow, 'group.KarlAdmin', ADMINISTRATOR_PERMS))&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;acl.append((Allow, moderators_group_name, MODERATOR_PERMS))&lt;/span&gt; &lt;br /&gt;&lt;span style="padding-left:26px"&gt;acl.append((Allow, members_group_name, MEMBER_PERMS))&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;acl.append(NO_INHERIT)&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;msg = None&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;added, removed = acl_diff(showEvent, acl)&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;if added or removed:&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:52px"&gt;showEvent.__acl__ = acl&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:52px"&gt;msg = ts('showEvent-private', model_path(showEvent), added, removed)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;_reindex(showEvent)&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;return msg&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;def showEvent_to_public(ob, info):&lt;br /&gt;&lt;span style="padding-left:26px"&gt;showEvent = find_showEvent(ob)&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;acl = []&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;moderators_group_name = showEvent.moderators_group_name&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;members_group_name = showEvent.members_group_name&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;acl.append((Allow, 'group.KarlAdmin', ADMINISTRATOR_PERMS))&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;acl.append((Allow, members_group_name, GUEST_PERMS))&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;acl.append((Allow, 'group.KarlStaff', GUEST_PERMS))&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;acl.append(NO_INHERIT)&lt;/span&gt; &lt;br /&gt;&lt;span style="padding-left:26px"&gt;msg = None&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;added, removed = acl_diff(showEvent, acl)&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;if added or removed:&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:52px"&gt;showEvent.__acl__ = acl&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:52px"&gt;msg = ts('showEvent-public', model_path(showEvent), added, removed)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;_reindex(showEvent)&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;return msg&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;def showEvent_to_pending(ob, info):&lt;br /&gt;&lt;span style="padding-left:26px"&gt;showEvent = find_showEvent(ob)&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;acl = []&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;moderators_group_name = showEvent.moderators_group_name&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;members_group_name = showEvent.members_group_name&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;acl.append((Allow, 'group.KarlAdmin', ADMINISTRATOR_PERMS))&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;acl.append((Allow, members_group_name, GUEST_PERMS)) #When the showEvent is pending user cannot delete,create, edit&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;acl.append((Allow, 'group.KarlStaff', GUEST_PERMS))&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;acl.append(NO_INHERIT) &lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;msg = None&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;added, removed = acl_diff(showEvent, acl)&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;if added or removed:&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:52px"&gt;showEvent.__acl__ = acl&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:52px"&gt;msg = ts('showEvent-pending', model_path(showEvent), added, removed)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;_reindex(showEvent)&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;return msg&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;def showEvent_to_rejected(ob,info):&lt;br /&gt;&lt;span style="padding-left:26px"&gt;showEvent = find_showEvent(ob)&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;acl = []&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;moderators_group_name = showEvent.moderators_group_name&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;members_group_name = showEvent.members_group_name&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;acl.append((Allow, 'group.KarlAdmin', ADMINISTRATOR_PERMS))&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;acl.append((Allow, members_group_name, GUEST_PERMS))&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;acl.append((Allow, 'group.KarlStaff', GUEST_PERMS))&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;acl.append(NO_INHERIT)  #temp&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;msg = None&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;added, removed = acl_diff(showEvent, acl)&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;if added or removed:&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:52px"&gt;showEvent.__acl__ = acl&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:52px"&gt;msg = ts('showEvent-pending', model_path(showEvent), added, removed)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;_reindex(showEvent)&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;return msg&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;In workflow.py permissions were imported from policy file. Below is the policy file of security_policies of project.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;policy.py&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;table class="zeroBorder" border="0" cellpadding="12" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#d0d0ff"&gt;from BTrees.IFBTree import multiunion&lt;br /&gt;from BTrees.IFBTree import IFSet&lt;br /&gt;&lt;br /&gt;from repoze.bfg.security import Allow&lt;br /&gt;from repoze.bfg.security import Deny&lt;br /&gt;from repoze.bfg.security import Everyone&lt;br /&gt;from repoze.bfg.security import AllPermissionsList&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;VIEW = 'view'&lt;br /&gt;EDIT = 'edit'&lt;br /&gt;CREATE = 'create'&lt;br /&gt;DELETE = 'delete'&lt;br /&gt;MODERATE = 'moderate'&lt;br /&gt;ADMINISTER = 'administer'&lt;br /&gt;COMMENT#acl.append((Allow, moderators_group_name, MODERATOR_PERMS))&lt;span style="padding-left:26px"&gt; #Creator or member is the part of default member group = 'comment'&lt;br /&gt;&lt;br /&gt;GUEST_PERMS = (VIEW, COMMENT)&lt;br /&gt;MEMBER_PERMS = GUEST_PERMS + (EDIT, CREATE, DELETE)&lt;br /&gt;MODERATOR_PERMS = MEMBER_PERMS + (MODERATE,)&lt;br /&gt;ADMINISTRATOR_PERMS = MODERATOR_PERMS + (ADMINISTER,)&lt;br /&gt;&lt;br /&gt;ALL = AllPermissionsList()&lt;br /&gt;NO_INHERIT = (Deny, Everyone, ALL)&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Add workflow.zcml and declare the states and transitions as follows.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;workflow.zcml&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;table class="zeroBorder" border="0" cellpadding="12" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#d0d0ff"&gt;&lt;br /&gt;&lt;span&gt;&lt;&lt;/span&gt; &lt;span style="padding-left:2px"&gt;configure xmlns="http://namespaces.repoze.org/bfg"&gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="padding-left:26px"&gt;&lt;&lt;/span&gt; &lt;span style="padding-left:2px"&gt;include package="repoze.workflow" file="meta.zcml"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span style="padding-left:78px"&gt;&lt;&lt;/span&gt; &lt;span style="padding-left:2px"&gt;    workflow type="security"&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:78px"&gt;name="showEvent"&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:78px"&gt;description="WF for showEvent"&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:78px"&gt;elector="project.workflow.not_intranets_containment"&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:78px"&gt;content_types="project.interfaces.IshowEvent"&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:78px"&gt;initial_state="private"&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:78px"&gt;state_attr="security_state"&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:78px"&gt;permission_checker="repoze.bfg.security.has_permission"&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:78px"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;  &lt;&lt;/span&gt; &lt;span style="padding-left:2px"&gt;state name="public" title="Public"&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:78px"&gt; callback="project.workflow.showEvent_to_public"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;  &lt;&lt;/span&gt; &lt;span style="padding-left:2px"&gt;/state&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;  &lt;&lt;/span&gt; &lt;span style="padding-left:2px"&gt;state name="private" title="Private"&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:78px"&gt; callback="project.workflow.showEvent_to_private"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:52px"&gt;   &lt;&lt;/span&gt; &lt;span style="padding-left:2px"&gt;alias name="initial"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;  &lt;&lt;/span&gt; &lt;span style="padding-left:2px"&gt;/state&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;  &lt;&lt;/span&gt; &lt;span style="padding-left:2px"&gt;state name="pending" title="Pending"ar&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:78px"&gt; callback="project.workflow.showEvent_to_pending"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;  &lt;&lt;/span&gt; &lt;span style="padding-left:2px"&gt;/state&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;  &lt;&lt;/span&gt; &lt;span style="padding-left:2px"&gt;state name="rejected" title="Rejected"&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:78px"&gt; callback="project.workflow.showEvent_to_rejected"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:52px"&gt;  &lt;&lt;/span&gt; &lt;span style="padding-left:2px"&gt;alias name="initial"&gt; &lt;!-- b/c --&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;  &lt;&lt;/span&gt; &lt;span style="padding-left:2px"&gt;/state&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;  &lt;&lt;/span&gt; &lt;span style="padding-left:2px"&gt;transition name="submit"&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:104px"&gt;  to_state="pending"&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:104px"&gt;  from_state="private"/&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;  &lt;&lt;/span&gt; &lt;span style="padding-left:2px"&gt;transition name="approve"&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:104px"&gt;  to_state="public"&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:104px"&gt;  from_state="pending"/&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;  &lt;&lt;/span&gt; &lt;span style="padding-left:2px"&gt;transition name="retract"&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:104px"&gt;  to_state="private"&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:104px"&gt;  from_state="pending"/&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;  &lt;&lt;/span&gt; &lt;span style="padding-left:2px"&gt;transition name="reject"&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:104px"&gt;  to_state="rejected"&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:104px"&gt;  from_state="pending"/&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="padding-left:26px"&gt;  &lt;&lt;/span&gt; &lt;span style="padding-left:2px"&gt;transition name="unapprove"&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:104px"&gt;  to_state="pending"&lt;/span&gt;&lt;br /&gt;&lt;span style="padding-left:104px"&gt;  from_state="public"/&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;&lt;span style="padding-left:2px"&gt;/workflow&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/configure&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Now register the workflow , by declaring it in configure.zcml file.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;configure.zcml&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;table class="zeroBorder" border="0" cellpadding="12" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#d0d0ff"&gt;&lt;br /&gt;&lt;br /&gt;&lt;&lt;span style="padding-left:2px"&gt;configure xmlns="http://namespaces.repoze.org/bfg"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;&lt;span style="padding-left:2px"&gt;!-- this must be included for the view declarations to work --&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;&lt;span style="padding-left:2px"&gt;include package="repoze.bfg.includes"&gt;&lt;/span&gt;&lt;br /&gt;  &lt;&lt;span style="padding-left:2px"&gt;include package="project.security_policies"&gt;&lt;/span&gt;&lt;br /&gt;  &lt;&lt;span style="padding-left:2px"&gt;include package="project.views"&gt;&lt;/span&gt;&lt;br /&gt;  &lt;&lt;span style="padding-left:2px"&gt;include package="project" file="workflow.zcml"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;&lt;span style="padding-left:2px"&gt;/configure&gt;&lt;/span&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;This way, we were able to create a workflow for our project.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/277432651694323775-1541511535903626656?l=srikanth-suri.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://srikanth-suri.blogspot.com/feeds/1541511535903626656/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://srikanth-suri.blogspot.com/2010/02/how-to-create-workflow-for-repoze.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/277432651694323775/posts/default/1541511535903626656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/277432651694323775/posts/default/1541511535903626656'/><link rel='alternate' type='text/html' href='http://srikanth-suri.blogspot.com/2010/02/how-to-create-workflow-for-repoze.html' title=''/><author><name>Srikanth.T</name><uri>http://www.blogger.com/profile/06764094427574143045</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-277432651694323775.post-7916772488344308426</id><published>2010-01-28T23:42:00.000-08:00</published><updated>2010-01-28T23:44:20.107-08:00</updated><title type='text'>Cataloging objects in BFG</title><content type='html'>&lt;div&gt;&lt;b&gt;&lt;span style="font-size:180%;"&gt;Cataloging objects in BFG&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;One way to catalog the objects in a BFG application is to use subscribers .&lt;br /&gt;The procedure followed to catalog is :&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Add a catalog file in the root that has a method to catalog the objects.&lt;/li&gt;&lt;li&gt;In models.py import the catalog method you have written and call it in the appmaker() .&lt;/li&gt;&lt;li&gt;Implement  zope events interfaces that you require in events.py (you can use any name)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Then write the functions which you want to execute on firing of above mentioned/decalred events.&lt;/li&gt;&lt;li&gt;Now use subscriber tag in configure.zcml and register the subscriber function to the events declared.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Let us see how we can catalog objects.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;catalog.py&lt;/b&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;        Create a python file called catalog.py in the root. Add a method &lt;span style="font-family:Courier New;"&gt;populate_catalog &lt;span style="font-family:Verdana;"&gt;and place the indexes that are required.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;import datetime&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;import time&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;from zope.interface import providedBy&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;from zope.component import queryAdapter&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;from zope.interface.declarations import Declaration&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;from repoze.bfg.traversal import model_path&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;from repoze.bfg.traversal import find_interface&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;from repoze.catalog.catalog import Catalog&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;from repoze.catalog.indexes.field import CatalogFieldIndex&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;from repoze.catalog.indexes.keyword import CatalogKeywordIndex&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;from repoze.catalog.indexes.text import CatalogTextIndex&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;from repoze.catalog.indexes.path import CatalogPathIndex&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;from repoze.catalog.indexes.path2 import CatalogPathIndex2&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;from repoze.catalog.document import DocumentMap&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;from repoze.bfg.security import principals_allowed_by_permission&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;from leavemnt.interfaces import IRoot&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;from leavemnt.interfaces import ISearchText&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;from leavemnt.interfaces import IVirtualData&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;from leavemnt.interfaces import ILeave&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;from leavemnt.interfaces import IProfile&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;from leavemnt.utils import coarse_datetime_repr&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;from leavemnt.utils import find_users&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;def get_search_text(object, default):&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    adapter = queryAdapter(object, ISearchText)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    if adapter is None:&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;        return defaul&lt;/span&gt;t&lt;/li&gt;&lt;li&gt;       &lt;span style="font-family:Courier New;"&gt;return adapter()&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;def get_creator(object, default):&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    return getattr(object, 'creator', default)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;def _get_date(object, default, name):&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    date = getattr(object, 'modified', None)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    if date is None:&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;        return default&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    # we can't store datetimes directly in the catalog because they&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    # can't be compared with anything&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    timetime = time.mktime(date.timetuple())&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    # creation "minute" actually to prevent too-granular storage&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    date = int(str(int(timetime))[:-2])&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    return date&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;def get_modified_date(object, default):&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    return _get_date(object, default, 'modified')&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;def get_created_date(object, default):&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    print _get_date(object, default, 'created')&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    return _get_date(object, default, 'created')&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;def get_interfaces(object, default):&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    # we unwind all derived and immediate interfaces using spec.flattened()&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    # (providedBy would just give us the immediate interfaces)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    provided_by = list(providedBy(object))&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    spec = Declaration(provided_by)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    ifaces = list(spec.flattened())&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    return ifaces&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;def get_security_state(obj, default):&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    return getattr(obj, 'security_state', default)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;def populate_catalog(site):&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    catalog = site.catalog   = Catalog()&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    catalog['text'] = CatalogTextIndex(get_search_text)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    catalog['interfaces'] = CatalogKeywordIndex(get_interfaces)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    catalog['creator'] = CatalogFieldIndex(get_creator)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    catalog['modified'] = CatalogFieldIndex(get_modified_date)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    catalog['created'] = CatalogFieldIndex(get_created_date)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    catalog['security_state']= CatalogFieldIndex(get_security_state)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    catalog.document_map = DocumentMap()&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;def find_catalog(context):&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    return find_interface(context, IRoot).catalog&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;In models.py&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;     In models , import populate_catalog from the catalog.py along with the necessary catalog methods from repoze.catalog .&lt;br /&gt;    Then in the appmaker function , make a site instance , and pass it as a parameter to the populate_catalog method.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;def appmaker(root):&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    if not root.has_key(SITE_ID):&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;        #site = root['site'] = Site()&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;        site = Site()&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;        root[SITE_ID] = site&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;        ## TODO: cleanup catalog creation.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;        populate_catalog(site)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;        leavefolder = LeaveFolder()&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;        site['leavefolder'] = leavefolder&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;        data = DefaultInitialData()&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;        transaction.commit()&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    return root[SITE_ID]&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-family:Courier New;"&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;"&gt;   Then the site will contain the catalog mechanism. For every subsequent creation, modification and deletion there should be a mechanism to update the catalog.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-family:Verdana;"&gt;&lt;b&gt;subscribers.py  &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-family:Verdana;"&gt;        The following code indexes, reindexes and unindexes on corresponding events.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;import datetime&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;from zope.component import queryAdapter&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;from repoze.bfg.traversal import model_path&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;from repoze.folder.interfaces import IFolder&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;from leavemnt.catalog import find_catalog&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;from leavemnt.interfaces import IMetadata&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;def postorder(startnode):&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    def visit(node):&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;        if IFolder.providedBy(node):&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;             for child in node.values():&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;                 for result in visit(child):&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;                     yield result&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;        yield node&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    return visit(startnode)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;def index_content(object, event):&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    """ Index content (an IObjectAddedEvent subscriber) """&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    catalog = find_catalog(object)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    if catalog is not None:&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;        for node in postorder(object):&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;                path = model_path(node)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;                docid = catalog.document_map.add(path)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;                catalog.index_doc(docid, node)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;                adapter = queryAdapter(node, IMetadata)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;                if adapter is not None:&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;                    metadata = adapter()&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;                    catalog.document_map.add_metadata(docid, metadata)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;def unindex_content(object, event):&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    """ Unindex content (an IObjectWillBeRemovedEvent subscriber) """&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    catalog = find_catalog(object)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    if catalog is not None:&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;        path = model_path(object)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;        num, docids = catalog.search(path=path)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;        for docid in docids:&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;            catalog.unindex_doc(docid)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;            catalog.document_map.remove_docid(docid)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;def reindex_content(object, event):&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    """ Reindex a single piece of content (non-recursive); an&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    IObjectModifed event subscriber """&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    catalog = find_catalog(object)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    if catalog is not None:&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;        path = model_path(object)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;        docid = catalog.document_map.docid_for_address(path)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;        catalog.reindex_doc(docid, object)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;        #catalog.document_map.remove_metadata(docid)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;        adapter = queryAdapter(object, IMetadata)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;        if adapter is not None:&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;            metadata = adapter()&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;            catalog.document_map.add_metadata(docid, metadata)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;        &lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;def set_modified(object, event):&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    """ Set the modified date on a single piece of content&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    unconditionally (non-recursive); an IObjectModified event&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    subscriber"""&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    now = datetime.datetime.now()&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    object.modified = now&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;def set_created(object, event):&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    """ Add modified and created attributes to nodes which do not yet&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    have them (recursively); an IObjectWillBeAddedEvent subscriber"""&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    now = datetime.datetime.now()&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    for node in postorder(object):&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;            if not getattr(node, 'modified', None):&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;                node.modified = now&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;            if not getattr(node, 'created', None):&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;                node.created = now&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-family:Verdana;"&gt;   When ever the event subscribed in configure.zcml is fired, approriate methods (in subscribers.py) is called.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Verdana;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:Verdana;"&gt;&lt;b&gt;configure.zcml&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;       In configure.zcml, make a subscriber tag and define the corresponding handlers, for an event.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;&lt;configure xmlns="http://namespaces.repoze.org/bfg"&gt;&lt;/configure&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;  &lt;!-- this must be included for the view declarations to work --&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;  &lt;include package="repoze.bfg.includes"&gt;&lt;/include&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;  &lt;include package="leavemnt.security_policies"&gt;&lt;/include&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;  &lt;include package="leavemnt.views"&gt;&lt;/include&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;  &lt;!--scan package="."/--&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;  &lt;static&gt;&lt;/static&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    name="static"&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    path="templates/static"&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;  &lt;subscriber&gt;&lt;/subscriber&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;      for="leavemnt.interfaces.ILeave&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;           repoze.folder.interfaces.IObjectWillBeRemovedEvent"&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;      handler=".subscribers.unindex_content" /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;  &lt;subscriber&gt;&lt;/subscriber&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;      for="leavemnt.interfaces.ILeave&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;           repoze.folder.interfaces.IObjectAddedEvent"&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;      handler=".subscribers.index_content" /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;  &lt;subscriber&gt;&lt;/subscriber&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;      for="leavemnt.interfaces.ILeave&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;           .interfaces.IObjectModifiedEvent"&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;      handler=".subscribers.reindex_content" /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;  &lt;subscriber&gt;&lt;/subscriber&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;      for="*&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;           repoze.folder.interfaces.IObjectWillBeAddedEvent"&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;      handler=".subscribers.set_created" /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;  &lt;subscriber&gt;&lt;/subscriber&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;      for="leavemnt.interfaces.IProfile&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;           repoze.folder.interfaces.IObjectWillBeRemovedEvent"&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;      handler=".subscribers.unindex_content" /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;  &lt;subscriber&gt;&lt;/subscriber&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;      for="leavemnt.interfaces.IProfile&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;           repoze.folder.interfaces.IObjectAddedEvent"&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;      handler=".subscribers.index_content" /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;  &lt;subscriber&gt;&lt;/subscriber&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;      for="leavemnt.interfaces.IProfile&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;           .interfaces.IObjectModifiedEvent"&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;      handler=".subscribers.reindex_content" /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;  &lt;subscriber&gt;&lt;/subscriber&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;      for="*&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;           .interfaces.IObjectModifiedEvent"&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;      handler=".subscribers.set_modified" /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;events.py&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;        in events.py define the events as required.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;from leavemnt.interfaces import IObjectModifiedEvent&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;from leavemnt.interfaces import IObjectWillBeModifiedEvent&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;from zope.interface import implements&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;class ObjectModifiedEvent(object):&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    implements(IObjectModifiedEvent)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    def __init__(self, object):&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;        print  object&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;        self.object = object&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;class ObjectWillBeModifiedEvent(object):&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    implements(IObjectWillBeModifiedEvent)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;    def __init__(self, object):&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Courier New;"&gt;        self.object = object&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/277432651694323775-7916772488344308426?l=srikanth-suri.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://srikanth-suri.blogspot.com/feeds/7916772488344308426/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://srikanth-suri.blogspot.com/2010/01/cataloging-objects-in-bfg.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/277432651694323775/posts/default/7916772488344308426'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/277432651694323775/posts/default/7916772488344308426'/><link rel='alternate' type='text/html' href='http://srikanth-suri.blogspot.com/2010/01/cataloging-objects-in-bfg.html' title='Cataloging objects in BFG'/><author><name>Srikanth.T</name><uri>http://www.blogger.com/profile/06764094427574143045</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-277432651694323775.post-4399633631333244779</id><published>2009-11-25T21:56:00.000-08:00</published><updated>2009-11-25T21:58:00.064-08:00</updated><title type='text'>How to setup SQLPASPlugin to authenticate against MYSQL database for Plone</title><content type='html'>&lt;p&gt;&lt;strong&gt;How To Setup SQLPASPlugin to Authenticate Against A MYSQL Database&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Site Configuration Details:&lt;/strong&gt;&lt;br /&gt;Here is some information on the site that I set this up on:&lt;br /&gt;&lt;br /&gt;&lt;em&gt;    *      Plone Version: 3.0&lt;br /&gt;    *      Zope Version: 2.9.3&lt;br /&gt;    *      Python Version: 2.4.4&lt;/em&gt;&lt;br /&gt;   &lt;br /&gt;&lt;strong&gt;Creation of Database:&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;SQLPASPlugin may be used to authenticate against any SQL Database for which there is a Zope connector available.&lt;br /&gt;&lt;br /&gt;*  Install MYSQL for the python in Zope Instance.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Installing SQLPASPlugin :&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt; To connect to the MYSQL database, Plone needs to use a database connector object which needs to be installed. To do this, download the latest version of MySQLdb.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;*  Extract the Archive MySQLdb , and install it at Plone-3.0/Python-2.4.4/lib/python2.4/MySQL-python-1.2.2&lt;br /&gt;&lt;br /&gt;*  Place this egg( MySQL_python-1.2.2-py2.4-linux-i686.egg ) in Site Pakages.&lt;br /&gt;&lt;br /&gt;*  Take the MySQL_python.egg-info egg and place it along with the MySQLdb i.e, at Plone-3.0/Python-2.4.4/lib/python2.4/MySQL-python-1.2.2.&lt;br /&gt;&lt;br /&gt;*  Place SQLPASPlugin in the Products.&lt;br /&gt;&lt;br /&gt;*  Place ZMySQLDA in the Products.&lt;br /&gt;&lt;br /&gt;Restart Zope.&lt;br /&gt;&lt;br /&gt;In the ZMI , in the Addable contents , now we can see the ZMySql Database Connection and ZSQL Method.&lt;br /&gt;&lt;br /&gt;Setup a connection to a database which is in mysql, using the ZMySql Database Connection.&lt;br /&gt;&lt;br /&gt;Add ZSQL Method and use the database.&lt;br /&gt;&lt;br /&gt;Now go to the Portal_Quick Installer and install SQLPASPlugin.&lt;br /&gt;And go to the plone_control_panel.&lt;br /&gt;In the Add-on Product Configuration , a link named SQL Authentication will be present. Click on it .&lt;br /&gt;You will be asked to specify the database for authentication. Check the MySQL database connection to setup the SQL Authenication.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/277432651694323775-4399633631333244779?l=srikanth-suri.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://srikanth-suri.blogspot.com/feeds/4399633631333244779/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://srikanth-suri.blogspot.com/2009/11/how-to-setup-sqlpasplugin-to.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/277432651694323775/posts/default/4399633631333244779'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/277432651694323775/posts/default/4399633631333244779'/><link rel='alternate' type='text/html' href='http://srikanth-suri.blogspot.com/2009/11/how-to-setup-sqlpasplugin-to.html' title='How to setup SQLPASPlugin to authenticate against MYSQL database for Plone'/><author><name>Srikanth.T</name><uri>http://www.blogger.com/profile/06764094427574143045</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
