mxm Workgroups for Plone
mxm Workgroups consists of three parts
- A Workgroup content type, that acts just like a normal Plone folder. With the difference that you can add members to it, and give these member local roles in the workgroup. These folders acts like Member folders, only for groups. Different groupmembers can have different roles.
- A workgroup tool that keeps track of the groups and their members. It registers the Workgroups internally for speed. This also means that Workgroup members does not need to have local roles in a workgroup to be members.
- A Workgroup workflow with an additional state "Visible for users" Content and Workgroups in this state can only be seen by members of the workgroup that has the local roles of "GroupMember" or "Owner" in that Workgroup.
Workgroup content type
A Workgroup is a fully functioning Plone folder, with a few additional tabs. It has workflow and metadata as you would expect.
A workgroup can be added anywhere in the portal. This means that even members can add add-hoc workgroups in their own home folder.
They also allow for easy sharing of workgroups that are outside the members folder. Ie. you can have a Workgroup called "news" in the root of the portal, and let any member add news items in this workgroup. Just as easily as if it was in his own home folder.
Members has a complete list of the groups they are group members of.
You can make groups that you are not a member of yourself. Which makes it easy for managers and others to make groups for others to use.
Group members can delegate their roles to others in a workgroup. Meaning ie. that if a Member has the "Reviewer" role, he can easily give it to other group members of the Workgroup.
The workgroup also has a simple email form, for sending emails to all group members.
Workgroup tool
The Workgroup tool keeps track of the Workgroups and the members in an efficient internal data structure (BTree's). No need to search the catalog.
Groups and members are referenced back and forth, so it is easy to get the members of a group, and the groups for a Memmber.
It is possible to move workgroups around without loosing the group/member relationships.
You can set up default roles that members get when they are added to a Workgroup.
My workgroups
The workgroup tool adds a new action/link to the "personal toolbar", where the Member can get a complete overview of the Workgroups he is a member of. Including the roles he has in the context of the Workgroup, and the subjects of the workgroup.
A Workgroup workflow
The Workgroup workflows are a pretty good base for developing your own workflows. They have one additional state: "Visible For Group".
The content in this state is only visible for members of the group with the local roles of "GroupMember" or "Owner"
This makes the Workgroups even more usable in many situations:
- A virtual classroom, where Teachers can add content and student can read only.
- Extranets, where the company can write, and customers can read only.
- A content portal, with exclusive content for specific members.
- Etc.
Compatibility
mxm Workgroups is compatible with Plone 2.x It might work under Plone 1.x if CMFFormController is installed.
But this setup is not tested!
Installation
It supports the quickinstaller tool under Plone 2.0 for install and uninstal.
Updating (important)
If you want to update from an older version of mxm Workgroups, you should not use the reinstall method! This is important, as you will loose all your Workgroup <> Members relations.
You should create an external method with the values:
Id: update_workgroup
Title:
Module Name: Workgroup.Install
Function Name: update
Then you should just click the test tab, and the Workgroups should be updated. Do yourself the favour of doing a backup of your Data.fs first though. You never know.
Portlets/boxes
The product includes some portlets.
Member's Workgroups
Visitors can see the workgroups that a Member is participating in.
Workgroup Members
The workgroup has a list of it's members in the right hand side.
Send mail to group
If you have the right permission, you can send an email to a group via a form.
License
GPL
Issues
Please send them to me at maxm@mxm.dk, or post them here. If you post here, please leave your email address in the posting.
Download
Get it http://www.mxm.dk/products/public/mxmWorkgroups/download/
I got a relevant question from Tim TerlegÄrd on the Plone list. I thought I would put the answer here too.
Tim TerlegÄrd wrote:
>>mxm Workgroups makes collaboration easy and possible for networked and
>>virtual organisations. It is a way to make shared "workspaces" where
>>groups of people can collaborate. Yet it still has all the freedom,
>>flexibility and simplicity as a normal Plone folder.
>
> What differs mxm Workgroups from PloneWorkspace and GrufSpace?
PloneWorkspace --------------
"Workspaces are places to put temporary references to content you are currently working on. Workspaces are designed to help you navigate efficiently."
So a PloneWorkspace is a virtual place with only references to other content. If you add a document in a PloneWorkspace, it ends up somewhere else.
mxm Workgroups is a an actual folder with the content in it. So imho it is easier to use and understand.
GrufSpace ---------
GrufSpace (GS) and mxm Workgroups (mxm) have many similarities. They are both folder like objects that users can share.
mxm can do a few more things, and is most likely a lot faster to get a list of all the groups a member participates in. Due to the mxm_workgroup tool OOBTree implementation.
This also makes it easy to make catalog searches in all of a members Workgroups, by getting the workgroup paths:
memberid = 'maxm'
mxm_workgroups = context.mxm_workgroups
workgroups = mxm_workgroups.getGroupsForMemberId(memberid)
workgroup_paths = ['/'.join(wg.getPhysicalPath()) for wg in workgroups]
catalog = context.portal_catalog
all_content_from_all_workgroups = catalog(path=workgroup_paths)
The workgroup_paths can then be used in the catalog query. So it is practical ie. to see all events in all workgroups.
In a setting with many members and groups, like an educational institution, or a big company, it should have a significant speed advantage.
GS: GS membership is defined by users having a local role. mxm: Group membership is defined by a reference to a member. So you can be a member without having a local role.
This makes it possible to have be a member of a group where you don't have any elevated rights. Ie. if you don't participate in a group but only need easy acces to view the groups content.
This also delays the point where it is nessecary to fiddle around with Permissions in a group.
mxm: Non invasive. No dependencies. Easy to install. Documented, working.
It is thought as an end user tool, so I have tried to make it easy to install, use and understand.
Plone 1.0.5?
I have yet to make the switch to 2.0, but this product looks like something we could start using right away. Thanks!
Add Member error
Error Type
RuntimeError
Error Message
FS Page Template WorkgroupMembers_Form has errors: Compilation failed.
<pre>TAL.TALDefs.TALError: Python expression error: invalid syntax (Python expression "test(search_submitted, mtool.searchForMembers( {request.get('search_param',''): request.get('search_term', '')}), None)", line 1) in expression "python:test(search_submitted, mtool.searchForMembers(\r\n {request.get('search_param',''):\r\n request.get('search_term', '')}), None)", at line 12, column 3</pre>
Replies to this comment
Compatibility
Replies to this comment
Great Product
ZMI oddity
Replies to this comment
mmx Workgroups and security settings
My problem is when I try to do this in other places then a member folder. I placed a workgroup in our /support folder and tried to make it visible to only the workgroup members. Now right after creating the workgroup and going to the "Security" tab from the ZMI and clicking on "Save Changes" (no changes made whatsoever) I am getting an error message:
"Some permissions had errors: Add Workgroups, Edit Workgroups, Manage Workgroup Membership"
Can you help with these settings?
Groups in groups
Member view
We need to set up each member "REVIEWVER" to see "private" in the navigation portlet.
Workgroup contents listing
On folders the doc list in the 'view' tab. On the workgroup, it doesn't. Is this by design, or do I have something set up wrong?
uninstalling removes states
Replies to this comment
Problem with LDAP
Sascha (Sascha dot Boch (at) jci.com)
Workgroup folder as portal tab
I added a few portal_tabs inside portal_actions, each linking to a workgroup folder. This works, but I would also like to let each tab show only for users which are members of the linked workgroup. What is the condition to use?
Thanks,
alf
Replies to this comment
Send Email to specific address
thx very much in advance!
mxm Workgroups 1.2
Replies to this comment
mmxWorkgroups
I am having some strange problems with the workgroup product.
It was working well but I think I crashed it when I upgraded â possiblyâŠ
The symptoms are that my users can ONLY publish â Plone lets them publish WITHOUT submitting!
This happened after the new version.
I have tried running the external method in your instructions and the output is fine saying that all went well.
Unfortunately I can access the folders because Plone gives a TAL error.
I have included a text file with the traceback.
I like having groups in my school situation but now I canât restrict publishing AND uninstalling does not help either because the permissions are still wrong.
Can you offer any suggestions?
Any help would be really appreciated.
Thanks
Peter Ashby
pashby@vhhs.sa.edu.au
http://vhhs.sa.edu.au
Traceback (innermost last):
Module ZPublisher.Publish, line 100, in publish
Module ZPublisher.mapply, line 88, in mapply
Module ZPublisher.Publish, line 40, in call_object
Module Shared.DC.Scripts.Bindings, line 306, in __call__
Module Shared.DC.Scripts.Bindings, line 343, in _bindAndExec
Module Products.CMFCore.FSPageTemplate, line 191, in _exec
Module Products.CMFCore.FSPageTemplate, line 124, in pt_render
Module Products.PageTemplates.PageTemplate, line 96, in pt_render
- <FSPageTemplate at /Plone/folder_contents used for /Plone/Members/Mr Ashby>
Module TAL.TALInterpreter, line 189, in __call__
Module TAL.TALInterpreter, line 233, in interpret
Module TAL.TALInterpreter, line 663, in do_useMacro
Module TAL.TALInterpreter, line 233, in interpret
Module TAL.TALInterpreter, line 408, in do_optTag_tal
Module TAL.TALInterpreter, line 393, in do_optTag
Module TAL.TALInterpreter, line 388, in no_tag
Module TAL.TALInterpreter, line 233, in interpret
Module TAL.TALInterpreter, line 694, in do_defineSlot
Module TAL.TALInterpreter, line 233, in interpret
Module TAL.TALInterpreter, line 629, in do_condition
Module TAL.TALInterpreter, line 233, in interpret
Module TAL.TALInterpreter, line 694, in do_defineSlot
Module TAL.TALInterpreter, line 233, in interpret
Module TAL.TALInterpreter, line 408, in do_optTag_tal
Module TAL.TALInterpreter, line 393, in do_optTag
Module TAL.TALInterpreter, line 388, in no_tag
Module TAL.TALInterpreter, line 233, in interpret
Module TAL.TALInterpreter, line 663, in do_useMacro
Module TAL.TALInterpreter, line 233, in interpret
Module TAL.TALInterpreter, line 629, in do_condition
Module TAL.TALInterpreter, line 233, in interpret
Module TAL.TALInterpreter, line 408, in do_optTag_tal
Module TAL.TALInterpreter, line 393, in do_optTag
Module TAL.TALInterpreter, line 388, in no_tag
Module TAL.TALInterpreter, line 233, in interpret
Module TAL.TALInterpreter, line 605, in do_loop_tal
Module TAL.TALInterpreter, line 233, in interpret
Module TAL.TALInterpreter, line 408, in do_optTag_tal
Module TAL.TALInterpreter, line 393, in do_optTag
Module TAL.TALInterpreter, line 388, in no_tag
Module TAL.TALInterpreter, line 233, in interpret
Module TAL.TALInterpreter, line 629, in do_condition
Module TAL.TALInterpreter, line 233, in interpret
Module TAL.TALInterpreter, line 408, in do_optTag_tal
Module TAL.TALInterpreter, line 393, in do_optTag
Module TAL.TALInterpreter, line 388, in no_tag
Module TAL.TALInterpreter, line 233, in interpret
Module TAL.TALInterpreter, line 649, in do_useMacro
Module Products.PageTemplates.TALES, line 220, in evaluate
- Line 35, Column 12
- Expression: <PythonExpr path(pathexpr)>
- Names:
{'container': <PloneSite instance at 0269BAA0>,
'context': <PloneFolder instance at 03B79A70>,
'default': <Products.PageTemplates.TALES.Default instance at 0x014C3EE0>,
'here': <PloneFolder instance at 03B79A70>,
'loop': <SafeMapping instance at 033F8D10>,
'modules': <Products.PageTemplates.ZRPythonExpr._SecureModuleImporter instance at 0x014BCB70>,
'nothing': None,
'options': {'args': ()},
'repeat': <SafeMapping instance at 033F8D10>,
'request': <HTTPRequest, URL=http://svr1/Members/Mr%20Ashby/folder_contents>,
'root': <Application instance at 03164EF0>,
'template': <FSPageTemplate at /Plone/folder_contents used for /Plone/Members/Mr Ashby>,
'traverse_subpath': [],
'user': Mr Ashby}
Module Products.PageTemplates.ZRPythonExpr, line 47, in __call__
- __traceback_info__: path(pathexpr)
Module Python expression "path(pathexpr)", line 1, in <expression>
Module Products.PageTemplates.PythonExpr, line 81, in __call__
Module Products.PageTemplates.Expressions, line 201, in __call__
Module Products.PageTemplates.Expressions, line 189, in _eval
Module Products.PageTemplates.Expressions, line 145, in _eval
- __traceback_info__: here
Module Products.PageTemplates.Expressions, line 347, in restrictedTraverse
- __traceback_info__: {'path': ['Workgroup_portlet_groups', 'macros', 'portlet'], 'TraversalRequestNameStack': ['portlet',
'macros']}
Module OFS.ObjectManager, line 656, in __getitem__
KeyError: 'Workgroup_portlet_groups'
install error in quickinstaller
I've tried to test this product, wich looks great, but I found an error. This is the log
Traceback (most recent call last):
File "d:\Archivos de programa\Plone 2\Data\Products\CMFQuickInstallerTool\QuickInstallerTool.py", line 216, in installProduct
File "C:\Archivos de programa\Plone 2\Zope\lib\python\Products\ExternalMethod\ExternalMethod.py", line 231, in __call__
return f(self.aq_parent.this(), *args, **kw)
File "C:\Archivos de programa\Plone 2\Data\Products\Workgroup\Extensions\Install.py", line 316, in install
setupTool(self, out)
File "C:\Archivos de programa\Plone 2\Data\Products\Workgroup\Extensions\Install.py", line 131, in setupTool
rs = membersFolder.right_slots
AttributeError: 'NoneType' object has no attribute 'right_slots'
thank you very much
svazquez at sadiel dot es
Replies to this comment
Popdown menu changed languages!
I have not modified or even worked with any of the localization tools! The "workgroup" item in the toolbar displays in English as it should, it's just the item beneath the add menu that changed languages!
How do I fix this? I'm new to Zope and Plone and don't have a clue of where to look! Your help is greatly appreciated - wonderful product by the way. Thx very much for all your efforts!
"Reply" tab
After creating a workgroup and activating the "Content" listing, a "Reply" tab appears, right after "Properties" (..../Workgroup/discussion_reply_form). Checked with /Plone/portal_types/Workgroup/manage_editActionsForm and there everything checks out OK, no "Reply" action. Here is the error message when I click on the "Reply" tab:
Site error
This site encountered an error trying to fulfill your request. The errors were:
Error Type
AttributeError
Error Value
showWizards
Request made at
2004/06/01 22:04:32.538 US/Pacific
As far as I can tell, this only happens with the Workgroup portal type. I am wondering if I am doing something wrong.
Replies to this comment
Group members
A question that is bothering me
Can standard group members change the content of their group folder - ie add files etc.
Mine can't without admin roles - is this the way it is supposed to be?
Peter
Make Workgroup Members portlet not visible to anonymous users
How do I turn off the visibility of the "Workgroup Members" porlet for anonymous users? Any help is appreciated.
great product! thx,
Replies to this comment
Good product but there are some problems
I made a french traduction for MxmWorkGroup : http://macadames.com/Plone2/fonctionnalites/ajout_produit/mxmworkgroups-fr.po.zip
Sorry for my bad english, i will try to tell about some problems with MxmWorkGroup :
After install in a Plone site the default workflow is modified, however my workflows were not so bad ... Hmm !
After install, all non folderish contents states are changed to "Visible" state ... Hmmm ! if you try to install MxmWorkGroup upon a big site in production with thousands of documents and files, perhaps you will get some displeasure, no ?
Replies to this comment
About adding MxmWorkGroup on a production site
Sorry for my approximative english
I think it's possible to add a new product on a production site, of course you need to test it on a copy of the site.
I'm not so stupid, ...
I have installed MxmWorkGroup in a big site (Plone2) folowing these lines :
1. in my portal_workflow, for each content workflow (document, news, events...) i change "(Default)" for "plone_workflow"
2. I install MxmWorkGroup (quickinstaller or externalmethod or ploneControlPanel > add product)
3. in my portal_workflow > plone_workflow i create the new states and transitions as done in your workgroup_content_workflow (visible4group, publish2group ...), i change all states permissions and transitions as done in your workgroup_content_workflow
4. i change portal_workflow > (Default) from "workgroup_content_workflow" to "plone_workflow"
Now everything works fine. I'm really happy.
However a problem remains, even when i add MxmWorkGroup on a brand new site :
i can't change roles for groupmembers
Plone responds "Insufficient privileges"
I use Plone 2.0RC5 and Plone 2.0RC6 (=2.0?) ....
i don't know what to do.
I really appreciate your product.
Translation and Search Errors
Lastly, when I try to add users to a Workgroup, I have to use "search". But searching by name returns "AttributeError" "email". When searching by "email", I get the error "AttributeError" "getProperty". Any ideas why?
WorkGroup Membership Expiration
Folder view
Replies to this comment
Error: Deletion of a workgroup containing a copied workgroup corrupts member accounts
The problem, is that to create the base content for the new client, we copy a template of content from another area of the site. This becomes a problem when we try to delete the main client folder.
It seems, based upon our testing, when you create a workgroup (wrk-dest), and copy an existing workgroup from another location (wrk-orig), when you delete wrk-dest it corrupts the user accounts that are members of the wrk-dest workgroup. When you log-in as an affected user and try to go to their "my workgroups", "my folder", or homepage, you get an error which we have in several cases been unable to fix.
Please advise,
Todd
tcrames@sytel.com
Here is a test-case that consistently reproduces this problem:
Prerequisites
Verify folder "My Projects" exists at root of plone site
Verify folder "Sandbox" exists at root of plone site
Steps
1.1.1 Login as admin
1.1.2 Create new user (ie. "testXX")
1.1.3 Create workgroup in "Sandbox" (ie. "wrk-orig")
1.1.4 Create workgroup in "My Projects" (ie. "wrk-dest")
1.1.5 Add user from step #1.1.2 (testXX) as a member of the workgroup created in step #1.1.4 (wkr-dest) in the "My Projects" folder
1.1.6 Make the user from step #1.1.2 (testXX) a workgroup manager of the workgroup created in step #1.1.4 (wkr-dest) in the "My Projects" folder
1.1.7 COPY the workgroup from step #1.1.3 (wrk-orig) from the "Sandbox" folder into the workgroup created in step #1.1.4 (wrk-dest) in the "My Projects" folder
1.1.8 Logout
1.1.9 Login as the user from step #1.1.2 (testXX)
1.1.10 Verify access to ""my workgroups"", ""my folder"" and the user homepage are working."
1.1.11 Verify that the workgroup copied and pasted from step #1.1.3 (wrk-orig) appears within the workgroup from step #1.1.4 (wrk-dest)
1.1.12 Logout
1.1.13 Login as admin
1.1.14 Delete the root workgroup created in step #1.1.4 (wrk-dest) in the "My Projects" folder. (Don't delete the child workgroup beforehand)
1.1.15 Logout
1.1.16 Login as the user from step #1.1.2 (testXX)
1.1.17 Verify access to ""my workgroups"", ""my folder"" and the user homepage are working."
1.1.18 Verify that the workgroup from step #1.1.4 (wrk-dest) is deleted and not accessible by the user
Steps 1.1.17 and 1.1.18 result in failure, with the following error being generated:
Site Error
An error was encountered while publishing this resource.
KeyError
Sorry, a site error occurred.
Traceback (innermost last):
Module ZPublisher.Publish, line 163, in publish_module_standard
Module ZPublisher.Publish, line 127, in publish
Module Zope.App.startup, line 203, in zpublisher_exception_hook
Module ZPublisher.Publish, line 100, in publish
Module ZPublisher.mapply, line 88, in mapply
Module ZPublisher.Publish, line 40, in call_object
Module Shared.DC.Scripts.Bindings, line 306, in __call__
Module Shared.DC.Scripts.Bindings, line 343, in _bindAndExec
Module Products.CMFCore.FSPageTemplate, line 191, in _exec
Module Products.CMFCore.FSPageTemplate, line 124, in pt_render
Module Products.PageTemplates.PageTemplate, line 96, in pt_render
<FSPageTemplate at /aes/Workgroup_myGroups used for /aes/Members/testXX>
Module TAL.TALInterpreter, line 189, in __call__
Module TAL.TALInterpreter, line 233, in interpret
Module TAL.TALInterpreter, line 663, in do_useMacro
Module TAL.TALInterpreter, line 233, in interpret
Module TAL.TALInterpreter, line 408, in do_optTag_tal
Module TAL.TALInterpreter, line 393, in do_optTag
Module TAL.TALInterpreter, line 388, in no_tag
Module TAL.TALInterpreter, line 233, in interpret
Module TAL.TALInterpreter, line 686, in do_defineSlot
Module TAL.TALInterpreter, line 233, in interpret
Module TAL.TALInterpreter, line 459, in do_setLocal_tal
Module Products.PageTemplates.TALES, line 220, in evaluate
Line 136, Column 20
Expression: <PythonExpr sequence.sort( mxm_workgroups.getGroupsForMember(member), [ ['Title', 'nocase', 'asc'], ['getId', 'nocase', 'asc'] ])>
Names:
{'container': <PloneSite instance at 43ba46b0>,
'context': <PloneFolder instance at 4406def0>,
'default': <Products.PageTemplates.TALES.Default instance at 0x40ce370c>,
'here': <PloneFolder instance at 4406def0>,
'loop': <SafeMapping instance at 44291fe0>,
'modules': <Products.PageTemplates.ZRPythonExpr._SecureModuleImporter instance at 0x40ce30ec>,
'nothing': None,
'options': {'args': ()},
'repeat': <SafeMapping instance at 44291fe0>,
'request': <HTTPRequest, URL=http://portal.sytel.com:8080/aes/Members/testXX/Workgroup_myGroups>,
'root': <Application instance at 43bfabf0>,
'template': <FSPageTemplate at /aes/Workgroup_myGroups used for /aes/Members/testXX>,
'traverse_subpath': [],
'user': testXX}
Module Products.PageTemplates.ZRPythonExpr, line 47, in __call__
__traceback_info__: sequence.sort( mxm_workgroups.getGroupsForMember(member), [ ['Title', 'nocase', 'asc'], ['getId', 'nocase', 'asc'] ])
Module Python expression "sequence.sort( mxm_workgroups.getGroupsForMember(member), [ ['Title', 'nocase', 'asc'], ['getId', 'nocase', 'asc'] ])", line 1, in <expression>
Module Products.Workgroup.mxmWorkgroupTool, line 208, in getGroupsForMember
Module Products.Workgroup.mxmWorkgroupTool, line 104, in _getByPaths
Module OFS.Traversable, line 204, in restrictedTraverse
Module OFS.Traversable, line 185, in unrestrictedTraverse
__traceback_info__: ([], 'wrk-dest')
Module OFS.ObjectManager, line 656, in __getitem__
KeyError: 'wrk-dest' (Also, an error occurred while attempting to render the standard error message.)
--------------------------------------------------------------------------------
Troubleshooting Suggestions
The URL may be incorrect.
The parameters passed to this resource may be incorrect.
A resource that this resource relies on may be encountering an error.
For more detailed information about the error, please refer to error log.
If the error persists please contact the site maintainer. Thank you for your patience.
Group Member, Group Leader, Group Admin
One thought I had is the Group Admin should have site admin like permissions to the Workgroup. Is this the default permissions when I install mxm Workgroups? Or do I need to customize the Workgroup security to achieve this purpose?
Work Group vs Wiki
Checkbox for "Check all"
group mail problem with : character
a.ullman@edfac.usyd.edu.au
Members won't list
All has been working really well with student groups, however lately I have been getting this message when I or users try to list members.
The important part of the traceback follows
...
...
Module TAL.TALInterpreter, line 233, in interpret
Module TAL.TALInterpreter, line 459, in do_setLocal_tal
Module Products.PageTemplates.TALES, line 220, in evaluate
Module Products.PageTemplates.ZRPythonExpr, line 47, in __call__
__traceback_info__: mxm_workgroups.getGroupsForMemberId(member_id)
Module Python expression "mxm_workgroups.getGroupsForMemberId(member_id)", line 1, in <expression>
Module Products.Workgroup.mxmWorkgroupTool, line 218, in getGroupsForMemberId
Module Products.CMFCore.MembershipTool, line 320, in getMemberById
Module Products.GroupUserFolder.GroupUserFolder, line 336, in getUserById
Module Products.GroupUserFolder.GroupUserFolder, line 285, in getUser
AttributeError: 'NoneType' object has no attribute 'startswith' (Also, an error occurred while attempting to render the standard error message.)
This has only happened recently and I can't think of changes I have made.
Thanks Peter
pashby@vhhs.sa.edu.au
Replies to this comment
Security inheritance and searching
Thanks for all your work on this product - it is excellent. However, can I just check something? when I set the workgroup state to private or visible for group, I would expect all content to be hidden. However, a search by an anonymous user can still find this hidden content (although they need the right permission to read the document itself). How can the search be disabled for content within a group whose content is not 'open'?
Thanks for your help!
suddenly insufficient priviliges
I reinstalled the MXMworkgroups, updating from 1.2.3 to 1.2.4 in the proces. Now it works again. Any ideas what happened.
regards,
constantin
TypeError: can only concatenate tuple (not "list") to tuple
Thanks for the great product.
On upgrading Workgroups I now get this error when I try to add a Workgroup. Also, I get Insufficient Privileges when I try to go to previous groups.
Thanks,
Ursine
<snip>
Module Products.ZCatalog.Catalog, line 381, in catalogObject
Module Products.PluginIndexes.common.UnIndex, line 242, in index_object
Module Products.PluginIndexes.KeywordIndex.KeywordIndex, line 61, in _index_object
Module Products.PluginIndexes.KeywordIndex.KeywordIndex, line 94, in _get_object_keywords
Module Products.CMFCore.CatalogTool, line 63, in allowedRolesAndUsers
Module Products.CMFCore.utils, line 215, in _mergedLocalRoles
TypeError: can only concatenate tuple (not "list") to tuple
Group Mail Feature has formatting problems
Message Body Paragraph 1
Message Body Paragraph 2
Signature
which was received as email rearranged by MXMWorkgroups as follows.
Message Body Paragraph 1
Recipient List
Message Body Paragraph 2 (no paragraph break) Signature
All paragraphs run together (the email does not seem to recognize line breaks).
-- harlow pinson
hpinson@indepthl.com
Roles cannot be changed
Replies to this comment
can only concatenate tuple (not "list") to tuple
MXMWorkgroup 1.2.4, Plone 2.0.4, Zope 2.7.2
GroupMember Security Issue
Isn't the user should have GroupMember role *and* be in the workgroup member list in order to view the content if the state is set to "visible for group"?
Am I missing something in the concept?
Thanks!
Cut and Paste MXMWorkgroups
Replies to this comment
Workgroups non visible in navigation-box?
I can change this by changing the navtree_properties (adding to "rolesSeeUnpublishedContent" the role "GroupMember"). But I'm not convinced by this solution because all content which is "non visible" now is visible for the GroupMembers.
I can also use the "trick" to enter the workgroup using a link from a document (creating a document in a folder higher than den workgroup and metting a link from this document to the workgroup); once entered the workgroup at this way it's also visible in the navigation-box. But this is very complicated.
Is there a resolution for this problem?
Thanks,
Paul
CMF Member compatibility
Very nice product. Have been testing it with Plone 2.04 and all was good. We them moved on to test with CMF Member 1.0 beta4. We ran into a problem when Workgroup_portlet_groups was called by the members folder. We removed the portlet .. here/Workgroup_portlet_groups/macros/portlet and all was well again. Have not tested the other workgroup portlets.
Here is an abreviated traceback.
âą Module Products.PageTemplates.TALES, line 220, in evaluate
URL: /plone/main_template
Line 16, Column 12
Expression: <PythonExpr mxm_workgroups.getGroupsForMemberId(member_id)>
Names:
Not sure if some accessors got renamed in CMF Member that mxm_workgroups is relying upon or if we have a problem on our end. Have you run into this problem before?
Dan
How to limit changing state of workgroup
Replies to this comment
news only for a specific workgroup
I've just started to use it and I am reallly impressed. Works fine :-)
But one thing I can't fix:
If I create a news-document in a news-folder in the workgroup, the created news can be seen by everyone. Is there a chance to generate specific news only for a workgroup, so that this news can't be seen by anyone except the workgroup members?
thank you very much
best regards
rue
Ruediger Mach
info@arteng.de
error when trying to install workgroups
2004-11-04 17:21:55
failed:
Traceback (most recent call last):
File "/usr/local/Zope/instance/Products/CMFQuickInstallerTool/QuickInstallerTool.py", line 235, in installProduct
res=install()
File "/usr/local/Zope/lib/python/Products/ExternalMethod/ExternalMethod.py", line 231, in __call__
return f(self.aq_parent.this(), *args, **kw)
File "/usr/local/Zope/instance/Products/Workgroup/Extensions/Install.py", line 316, in install
setupTool(self, out)
File "/usr/local/Zope/instance/Products/Workgroup/Extensions/Install.py", line 131, in setupTool
rs = membersFolder.right_slots
AttributeError: 'NoneType' object has no attribute 'right_slots'
this was on a zope/plone running on a linux machine. i also installed the product on a windows machine w/out any problems.
what can be wrong here?
--
ulf
Replies to this comment
Install detail
out.write('| | | | %s<br>\n' % subObj )
/srv/www/zope/Products/Workgroup/__init__.py:14: DeprecationWarning: Non-ASCII character '\xa0' in file /srv/www/zope/Products/Workgroup/mxmWorkgroupTool.py on line 400, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details
import Workgroup, mxmWorkgroupTool
/srv/www/zope/Products/Workgroup/mxmWorkgroupTool.py:23: DeprecationWarning: Non-ASCII character '\xe9' in file /srv/www/zope/Products/Workgroup/Relations.py on line 26, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details
from Relations import Relations
Replies to this comment
Sending Emails Through Bcc???
Subgroups only automatically available for all users?
First of all, thank so much you for making the plone/zope experience easier for end users.
Down to the question: I would like to have reviewers in the Workgroup A (this is not an issue since I can add members to it manually) and then have any member of the site to be able to SUBMIT content automatically to Subworkgroup B (which then would be submitted to the above reviewers).
Since I have dozens of Subworkgroups and many many users signing up every day, continually adding all these users to subgroups looks frightening.
Any idea ? I would really appreciate if you could point me in the right direction.
Thanks a lot dan
oso<>nettarine.com
Removing Members folder breaks installer
The traceback:
failed:Traceback (most recent call last): File "/home/zopeuser/hymne/Products/CMFQuickInstallerTool/QuickInstallerTool.py", line 216, in installProduct res=install() File "/usr/local/www/Zope/lib/python/Products/ExternalMethod/ExternalMethod.py", line 232, in __call__ return f(self.aq_parent.this(), *args, **kw) File "/home/zopeuser/hymne/Products/Workgroup/Extensions/Install.py", line 316, in install setupTool(self, out) File "/home/zopeuser/hymne/Products/Workgroup/Extensions/Install.py", line 131, in setupTool rs = membersFolder.right_slotsAttributeError: 'NoneType' object has no attribute 'right_slots'
Adding a group as a member of a workgroup
we use plone as intranet on a school with 50 teachers and 500 children.
i have added groups in plone (teachergroup, schooladministration, pupilsgroup and so on). we need this plone-groups for distributing the rights in our plone intranet (calendaring, adding content and so on).
now we tried mxmworkgroup. it works fine. we use it a a secure zone for the different groups.
so every plone-group has now its own mxmworkgroup. but i can't add a plone-group as a member of a mxmworkgroup. so i have to group the users again: checking all users belongig to the plone-teachergroup and make them members of the mxmworkgroup for the teachers.
problem: i always have to do the work again.
an other problem: if we get new pupils or teachers i have to add them to the plone-group AND to the mxmworkgroup.
is it possible to change mxmworkgroup for adding plonegroups as members?
Replies to this comment
Does mxm workgroups work on Plone 2.1?
Does mxm workgroups work on Plone 2.1? If not, there are any plans on if and when this is going to happen?
Many thanks for the fantastic product!
Replies to this comment
installation problem
Replies to this comment
Can't delegate roles
1. I created a workgroup folder
2. Added a member called "an62"
3. Made him a Manager, Member, GroupMember, Owner, Reviewer of the workgroup folder
4. He logged-in
5. He went inside the newly created workgroup folder
6. He went to workgroup roles
7. He added another member called "bz33"
8. Tried to delegate the Reviewer role to "bz33" by checking the Reviewer checkbox
9. Clicked on the "Ok" button
10. The check disappeared from bz33's Reviewer checkbox
What could be going wrong here ?
Wh
Plone 2.1.1 results
Second FYI I installed a clean copy of Plone 2.1.1, then installed Workgroup 1.2.7. It appears to work just fine, although perhaps it doesn't take advantage of some new features. I'm especially happy that the email to group members is properly line-wrapped to match the contents field.
Third, the mxmworkgroups-plone-en.po file still uses the word 'arbejdsgruppe' instead of 'workgroup'. This is a BUG in your program, hope you can fix it with the next release!
Dan
Older items not showing up
thanks again.
Replies to this comment
URL Hackable
Thanks,
Veda (vedawms@unc.edu)
Replies to this comment
Backspace bug after logout
- Veda (vedawms@unc.edu)
Replies to this comment
Not understanding how to hide something from everyone *but* a group member
Replies to this comment
Sub Folder Permissions?
I have scenario like this that i wanna create a folder with name 'Documents' and wanna create three more folders in it with names 'Daily' , 'weekly' and 'monhtly' . And i want to assign seperate members to each folder.
So how should i do it?? Do i make workgroup with name 'Documents' and create three more workgroups inside it??
i am confused bcos when i assign any member to parent workgroup that member can access All children workgroups also.
Wats the correct way to do it?? can some body give me hint
workgroups wrt Plone
I'm new to Plone, learning to use it for a company project. I have a need for group space type products. I tried TeamSpaces, and have recently been exploring GrufSpaces. I found references to this Workgroups product in the mailing list. I'm interested in reviewing this product for use with by my company, but I'm curious about why this product is not listed on the Plone site with other groups related products. I do see "mxm Contacts" there, is there a reason this one seems to be living without official Plone Product status?
Workgroup inherit of a ATFolder??
Replies to this comment
Adding member to Workgroup causes error
When adding a member to a new Workgroup, I get:
Site error
This site encountered an error trying to fulfill your request. The errors were:
Error Type
RuntimeError
Error Value
Workgroup/skins/Workgroup/WorkgroupMembers_Form_add_validate.vpy has errors.
Request made at
2006/04/08 09:54:59.358 GMT-10
I also had some problems adding a workgroup in the first place, but I managed to get around that (it created a new workgroup with a datestamp instead of the name I gave it, but I was able to rename the workgroup... Still not able to create a named workgroup, but it's minor since I have one to work with now!)
Any ideas? Should I provide some more info? If so, what would you like?
Cheers!
Chris
San Francisco, USA
Recursively setting workgroup status to "Visible for group"
I failed to set the initial state for all workgroups to "visible for group".
By now, a lot of workgroups (and sub workgroups) have been created throughout our Plone site.
How do I go about setting all workgroup states accordingly ?
Regards,
Danny
email : d.sinang at spitech.com
duplicated content tab
In the main screen of a workgroup (Your first screenshot) the 'content'-tab is duplicated before the 'view'-tab.
Is it my installation? Any tips to change it?
Thanks
glynnyth@gmail.com
Replies to this comment
LinguaPlone
The content put in a workgroup is translatable, but how to have translations of eg the name of the workgroup.
Thanks for any suggestions
Workgroup members last login
Thanks for a great product, which our community have used a lot.
In our site we have some workgroups where we put documents which should be downloaded and read by the members. How could we get an extra column in the "workgroup members" view which show the time when the member had logged last? This would give us an easy way to spot people how have forgotten to login, so we could send them a reminder to do so.
Thanks for reading this.
Best regards AW.
Replies to this comment
mxm with Plone 2.5
Replies to this comment
Can we specify th ID ?
Is this possible ?
No Workgroup List in Plone 2.1.3
mxm workgroups is a great tool. I used it in 2.0.5 with great results. In 2.1.3 using custom skins, there is no "my workgroups" link in the personal bar.
The workgroups are set to visible to groupmembers, but when I log in under a workgroup member's account, I don't see the "my workgroups" link.
The workgroups work OK. They show up in recent activities portlet, and I can add content to them. i just need the "my workgroup" link to be visible.
Thanks,
Paul
Replies to this comment
no 'visible for workgroups' option
With ATworkgroups2.0 under Plone 2.5 i have no 'visible to workgoup' option. Also the 'my workgroups'-button in the personal bar doesnt appear. Both on a upgraded plonesite and a really fresh server. Some other workgroup-wroducts like 'Teamspace' have similar problems. So, do i need something in the background, which is not included in a standard plone-installation?
Bye uwe
AtWorkgroups 2.0 and Plone 2.51
Installing AtWorkgroups 2.0 (from Plone Softwarecenter or SVN, does not matter) gives the following error below if clicking on the "Member" folder of the site. If I remove the "here/portlet_Workgroup_groups/macros/portlet" from the right_slots property, the error will go away. This happens with both 2.8 and 2.9 versions of Zope.
I will send you more feedback through email.
Regards,
Zoltan
Site Error
An error was encountered while publishing this resource.
TypeError
Sorry, a site error occurred.
Traceback (innermost last):
Module ZPublisher.Publish, line 188, in publish_module_standard
Module Products.PlacelessTranslationService.PatchStringIO, line 34, in new_publish
Module ZPublisher.Publish, line 145, in publish
Module Zope2.App.startup, line 216, in zpublisher_exception_hook
Module ZPublisher.Publish, line 114, in publish
Module ZPublisher.mapply, line 88, in mapply
Module ZPublisher.Publish, line 40, in call_object
Module Shared.DC.Scripts.Bindings, line 311, in __call__
Module Shared.DC.Scripts.Bindings, line 348, in _bindAndExec
Module Products.PythonScripts.PythonScript, line 323, in _exec
Module None, line 2, in index_html
<PythonScript at /Plone/Members/index_html>
Line 2
Module Shared.DC.Scripts.Bindings, line 311, in __call__
Module Shared.DC.Scripts.Bindings, line 348, in _bindAndExec
Module Products.CMFCore.FSPageTemplate, line 195, in _exec
Module Products.CacheSetup.patch_cmf, line 18, in FSPT_pt_render
Module Products.CacheSetup.patch_utils, line 9, in call_pattern
Module Products.CMFCore.FSPageTemplate, line 134, in pt_render
Module Products.CacheSetup.patch_cmf, line 56, in PT_pt_render
Module Products.CacheSetup.patch_utils, line 9, in call_pattern
Module Products.PageTemplates.PageTemplate, line 104, in pt_render
<FSPageTemplate at /Plone/member_search_form used for /Plone/Members>
Module TAL.TALInterpreter, line 206, in __call__
Module TAL.TALInterpreter, line 250, in interpret
Module TAL.TALInterpreter, line 711, in do_useMacro
Module TAL.TALInterpreter, line 250, in interpret
Module TAL.TALInterpreter, line 426, in do_optTag_tal
Module TAL.TALInterpreter, line 411, in do_optTag
Module TAL.TALInterpreter, line 406, in no_tag
Module TAL.TALInterpreter, line 250, in interpret
Module TAL.TALInterpreter, line 742, in do_defineSlot
Module TAL.TALInterpreter, line 250, in interpret
Module TAL.TALInterpreter, line 677, in do_condition
Module TAL.TALInterpreter, line 250, in interpret
Module TAL.TALInterpreter, line 742, in do_defineSlot
Module TAL.TALInterpreter, line 250, in interpret
Module TAL.TALInterpreter, line 426, in do_optTag_tal
Module TAL.TALInterpreter, line 411, in do_optTag
Module TAL.TALInterpreter, line 406, in no_tag
Module TAL.TALInterpreter, line 250, in interpret
Module TAL.TALInterpreter, line 711, in do_useMacro
Module TAL.TALInterpreter, line 250, in interpret
Module TAL.TALInterpreter, line 677, in do_condition
Module TAL.TALInterpreter, line 250, in interpret
Module TAL.TALInterpreter, line 426, in do_optTag_tal
Module TAL.TALInterpreter, line 411, in do_optTag
Module TAL.TALInterpreter, line 406, in no_tag
Module TAL.TALInterpreter, line 250, in interpret
Module TAL.TALInterpreter, line 653, in do_loop_tal
Module TAL.TALInterpreter, line 250, in interpret
Module TAL.TALInterpreter, line 426, in do_optTag_tal
Module TAL.TALInterpreter, line 411, in do_optTag
Module TAL.TALInterpreter, line 406, in no_tag
Module TAL.TALInterpreter, line 250, in interpret
Module TAL.TALInterpreter, line 426, in do_optTag_tal
Module TAL.TALInterpreter, line 411, in do_optTag
Module TAL.TALInterpreter, line 406, in no_tag
Module TAL.TALInterpreter, line 250, in interpret
Module TAL.TALInterpreter, line 677, in do_condition
Module TAL.TALInterpreter, line 250, in interpret
Module TAL.TALInterpreter, line 426, in do_optTag_tal
Module TAL.TALInterpreter, line 411, in do_optTag
Module TAL.TALInterpreter, line 406, in no_tag
Module TAL.TALInterpreter, line 250, in interpret
Module TAL.TALInterpreter, line 711, in do_useMacro
Module TAL.TALInterpreter, line 250, in interpret
Module TAL.TALInterpreter, line 477, in do_setLocal_tal
Module Products.PageTemplates.TALES, line 221, in evaluate
URL: file:ATWorkgroup/skins/ATWorkgroup/portlet_Workgroup_groups.pt
Line 40, Column 12
Expression: <PythonExpr workgrouptool.getAccesibleGroupsForMember(member_id)>
Names:
{'container': <PloneSite at /Plone>,
'context': <ATBTreeFolder at /Plone/Members>,
'default': <Products.PageTemplates.TALES.Default instance at 0x010E2C60>,
'here': <ATBTreeFolder at /Plone/Members>,
'loop': <Products.PageTemplates.TALES.SafeMapping object at 0x04F755D0>,
'modules': <Products.PageTemplates.ZRPythonExpr._SecureModuleImporter instance at 0x010B2E90>,
'nothing': None,
'options': {'args': ()},
'repeat': <Products.PageTemplates.TALES.SafeMapping object at 0x04F755D0>,
'request': <HTTPRequest, URL=http://portal2.elan-gmk.com/Members/index_html>,
'root': <Application at >,
'template': <FSPageTemplate at /Plone/member_search_form used for /Plone/Members>,
'traverse_subpath': [],
'user': zoltan}
Module Products.PageTemplates.ZRPythonExpr, line 47, in __call__
__traceback_info__: workgrouptool.getAccesibleGroupsForMember(member_id)
Module Python expression "workgrouptool.getAccesibleGroupsForMember(member_id)", line 1, in <expression>
Module Products.ATWorkgroup.workgrouptool, line 345, in getAccesibleGroupsForMember
Module Products.ATWorkgroup.workgrouptool, line 334, in getGroupsForMember
Module Products.ATWorkgroup.workgrouptool, line 254, in _members2Ids
TypeError: iteration over non-sequence (Also, the following error occurred while attempting to render the standard error message, please see the event log for full details: iteration over non-sequence)
--------------------------------------------------------------------------------
Troubleshooting Suggestions
The URL may be incorrect.
The parameters passed to this resource may be incorrect.
A resource that this resource relies on may be encountering an error.
For more detailed information about the error, please refer to error log.
If the error persists please contact the site maintainer. Thank you for your patience.
atworkgroup 2.0 : about workflows and "visible for workgroup",
I sent an email, joigning french translation of the i18n of atworkgroup 2.0, 2 .po files, maxm@mxm.dk doesn't seem to work.
here they are:
http://www.afpy.org/Members/amine/mxmworkgroups-fr.po/file_view
http://www.afpy.org/Members/amine/mxmworkgroups-plone-fr.po/file_view
I'm using ATWorkgroup for a community project, exactly what i'm searching. Thanks a lot, really.
I'll soon send you arabic files as soon as they are finished.
I'm using ATWorkgroup 2.0, a silly question, may I?
file Extensions/Install.py :
147 try:
148 installWorkflows = ExternalMethod('temp',
149 'temp',
150 PROJECTNAME+'.InstallWorkflows',
151 'installWorkflows').__of__(self)
152 except NotFound:
153 installWorkflows = None
154
155 if installWorkflows:
156 setupWorkflows(self, out)
The try block always raise an error, so the except block set installWorkflows to None. so setupWorkflows(self, out) is never executed. The workflow installation in portal_workflow fails.
I changed it to:
155 if not installWorkflows:
156 setupWorkflows(self, out)
it install the 2 workflows, workgroup_workflow and workgroup_content_workflow, and transitions. it's patchy, but it work.
Is it a bug or intentional? or i have not read docs carefully?
PS: sorry for my horrible english.
Amine: rawhead@hotmail.fr
Replies to this comment
"visible for group" not visible
I've installed atworkgroup2.0.2 with plone 2.1.3 but "visible for group" is not visible
It's just to add another configuration info to the previous post
Otherwise thank you for the other products like mxm dynamicpage and now pagebuilder
regards
martin
configuration
# Plone Instance: 2.1.3
# Python: 2.3.5 (#2, Sep 4 2005, 22:01:42) [GCC 3.3.5 (Debian 1:3.3.5-13)]
# Zope: (Zope 2.8.6-final, python 2.3.5, linux2)
problem with initial state
I've got a problem with atworkgroup2.0.2 and plone2.1.3 when I set the initial state of the two specific workflows (workgroup_content_workflow and workgroup_workflow) to private: all the documents already existing in the site become private but not the folders and subfolders.
If now I set the initial state to visible all the documents already existing in the site become visible.
It seems to be the same with mxmworkgroup1.4.1 and plone2.1.3
Regards
martin
martindupond(at)free.fr
Folder Object lacks Visable By Group
Replies to this comment
Order in workgroup
It is working fine and seems to do what I need. The one problem I have not seen a way through is that unlike folders you cannot reorder the listing of items. Is there a way to do this, and I just haven't spotted it? Even if it were through the ZMI that would help.
Cheers
Replies to this comment
'NoneType' object is not callable
This is in relation to the function getAccesibleGroupMembers in portlet_Workgroup_members.pt. Like I said, it happens at random, I can't seem to find a scenario where this is repeatable, and sometimes clicking around the website for a while and coming back eliminates the error. Sometimes it doesn't. After I eliminate the error, I can't seem to find a way to trigger it again. This line is interesting:
Module None, line 319, in getAccesibleGroupMembers.
It seems to suggest the module (which should be the workgroup tool) is None. Something wrong with the tool registration that can cause random problems?
Remove Workgroup Portlet
Tom
Plone 3 and atworkgroups
I am using atworkgroups with my students to excellent effect.
In the future I would like to move to Plone 3.
Are you going to migrate this most useful tool to Plone 3?
Peter
apologies for the double post
an 'author' role?
I almost have the hang of mxmWorkgroups, but one thing eludes me that I'm sure is simple I just can't get it.
Basically what I want is the ability to add other modules to a workgroup, e.g. Blog, and then only a certain role, e.g. Author, can post these items. It seems that the roles Manager and Owner do everything, deleting etc., when all I want is a role that can only post items.
How might I achieve this?
Many thanks, neil.
Replies to this comment
Groupmember in ATWorkgroups - listed inside the portlet
Thanks.
Paul
Does a workgroup folder have to be created/visible?
Unauthorized: You are not allowed to manage portlets
ATWorkgroup-3.0.0 svn
Only members with "Manager" role can add ATWorkgroup. Any non-Manager role returns the following error:
Exception Type
Unauthorized
Exception Value
You are not allowed to manage portlets
Any ideas on how to correct?
****************************
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 Products.CMFPlone.FactoryTool, line 376, in __call__
Module ZPublisher.mapply, line 88, in mapply
Module ZPublisher.Publish, line 42, in call_object
Module Products.CMFFormController.FSControllerPageTemplate, line 90, in __call__
Module Products.CMFFormController.BaseControllerPageTemplate, line 28, in _call
Module Products.CMFFormController.ControllerBase, line 231, in getNext
Module Products.CMFFormController.Actions.TraverseTo, line 38, in __call__
Module ZPublisher.mapply, line 88, in mapply
Module ZPublisher.Publish, line 42, in call_object
Module Products.CMFFormController.FSControllerPythonScript, line 104, in __call__
Module Products.CMFFormController.Script, line 145, in __call__
Module Products.CMFCore.FSPythonScript, line 140, in __call__
Module Shared.DC.Scripts.Bindings, line 313, in __call__
Module Shared.DC.Scripts.Bindings, line 350, in _bindAndExec
Module Products.CMFCore.FSPythonScript, line 196, in _exec
Module None, line 1, in content_edit
- <FSControllerPythonScript at /Plone/content_edit used for /Plone/Members/brittany/portal_factory/ATWorkgroup/atworkgroup.2008-12-17.4325532704>
- Line 1
Module Products.CMFCore.FSPythonScript, line 140, in __call__
Module Shared.DC.Scripts.Bindings, line 313, in __call__
Module Shared.DC.Scripts.Bindings, line 350, in _bindAndExec
Module Products.CMFCore.FSPythonScript, line 196, in _exec
Module None, line 13, in content_edit_impl
- <FSPythonScript at /Plone/content_edit_impl used for /Plone/Members/brittany/portal_factory/ATWorkgroup/atworkgroup.2008-12-17.4325532704>
- Line 13
Module Products.Archetypes.BaseObject, line 669, in processForm
Module Products.ATWorkgroup.ATWorkgroup, line 130, in at_post_create_script
Module plone.app.portlets.utils, line 85, in convert_legacy_portlets
Module plone.app.portlets.checker, line 26, in __call__
Unauthorized: You are not allowed to manage portlets
BCC for Plone 2.5 and Workgroup 3.0
The solution involves the modification of 2 files: the mail template and the email mixin script. Here is a listing for the 2 files for your kind reference. Please note that this is a hack, works for me, but probably lacks error checking, test cases and optimization. Use if at your own risk, or ask Max real nicely to implement is as pros do :-)
--- listing of Workgroup_mailForm.pt ---
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US"
lang="en-US"
metal:use-macro="here/main_template/macros/master"
i18n:domain="ATWorkgroup">
<div metal:fill-slot="main"
tal:define="memberMails here/getAccesibleMemberMails">
<form class="group" name="mail_form" action="." method="post" enctype="multipart/form-data"
tal:attributes="action here/absolute_url">
<h1 i18n:translate="send_an_email">Send an email to the group</h1>
<br/>
<!-- Mail Subject -->
<div class="row">
<div class="label" i18n:translate="subject">Subject</div>
<div class="field">
<input type="text" name="subject" size="40"/>
</div>
</div>
<!-- Mail Body -->
<div class="row">
<div class="label" i18n:translate="body">Body</div>
<div class="field">
<textarea cols="80"
rows="15"
name="body"
></textarea>
</div>
</div>
<!-- Mail From -->
<div class="row">
<div class="label" i18n:translate="from">From</div>
<div class="field">
<input type="text" name="mfrom" size="32" tal:attributes="value python:member.getProperty('email', '')"/>
</div>
</div>
<!-- Recepients -->
<!-- create seperate To: and BCC: sections -->
<div class="label" i18n:translate="To">To</div>
<div class="field">
<input type="text"
name="to"
size="32"
tal:attributes="value python:member.getProperty('email', '')"/>
</div>
<div class="row">
<div class="label" i18n:translate="Bcc">Bcc:</div>
<div class="field">
<tal:block repeat="email memberMails">
<input class="noborder"
type="checkbox"
name="bcc:list" checked
tal:attributes="value email">
<a tal:attributes="href string:MAILTO:$email" tal:content="email" />
</tal:block>
</div>
</div>
<div class="row">
<div class="label" i18n:translate="Attachments">Attachment</div>
<div class="field">
<input name="attachments:list" type="file">
</div>
<div class="field">
<input name="attachments:list" type="file">
</div>
</div>
<!-- Submitting machinery -->
<div class="row">
<div class="label"></div>
<div class="field">
<input class="context" type="submit" name="Workgroup_mailFormAction:method" value=" Send "
i18n:attributes="value"/>
</div>
</div>
</form>
</div>
</html>
--- end listing of Workgroup_mailForm.pt ---
--- listing of EmailMixin.py ---
# python
import email
from email import Encoders
from email.Message import Message
from email.Header import Header
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
try:
set
except NameError:
from sets import Set as set
# zope
from BTrees.OOBTree import OOBTree
from ZODB.PersistentList import PersistentList
from AccessControl import ClassSecurityInfo
from DocumentTemplate.DT_Util import html_quote
# cmf
from Products.CMFCore.utils import getToolByName
# product
from Products.ATWorkgroup.config import *
View = 'View'
class OOBTreeWrapper:
"""
Makes a OOBTree readable
"""
__allow_access_to_unprotected_subobjects__ = 1
def __init__(self, obj):
self._obj = obj
def __getitem__(self, key):
if key == 'attachments':
attachments = self._obj[key]
return [OOBTreeWrapper(a) for a in attachments]
else:
return self._obj[key]
def __getattr__(self, attr):
return getattr(self._obj, attr)
class EmailMixin:
"""
This class is used to seperate oout all the email handling functions.
"""
security = ClassSecurityInfo()
def _props(self):
return getToolByName(self, 'portal_properties')
def _members_emails(self, members):
"Returns list of emails from list of members"
emails = []
for member in members:
stripped_mail = member.getProperty('email', '').strip()
if stripped_mail:
emails.append(stripped_mail)
return emails
security.declareProtected(Workgroup_mailPermission, 'getMemberMails')
def getMemberMails(self):
"Returns a list of all members email adress"
return self._members_emails(self.getGroupMembers())
security.declareProtected(Workgroup_mailPermission, 'getAccesibleMemberMails')
def getAccesibleMemberMails(self):
"Returns a list of all visible members email adress"
return self._members_emails(self.getAccesibleGroupMembers())
def _site_encoding(self):
"Returns the site encoding"
site_props = self._props().site_properties
return site_props.default_charset or 'utf-8'
def getSmtpHost(self):
mh = self.MailHost
return (mh.smtp_host, mh.smtp_port)
def _site_encoding(self):
"Returns the site encoding"
site_props = self._props().site_properties
return site_props.default_charset or 'utf-8'
def _mailhost(self):
# tries to fetch a mailhost
if hasattr(self, 'MailHost'):
return self.MailHost
def _getAttachments(self, attachments):
"""
Returns [{'filename':fn, 'contentType':ct, 'data':data},] for attachements
"""
if attachments is None:
attachments = []
attachments = [a for a in attachments if a]
result = []
if attachments:
for attachment in attachments:
headers = email.message_from_string(str(attachment.headers))
contentType = headers['Content-Type']
filename = headers.get_param('filename', 'Attachment', 'Content-Disposition')
# clean up IE paths
filename = filename[max(filename.rfind('/'),
filename.rfind('\\'),
filename.rfind(':')
)+1:]
data = attachment.read()
result.append({'filename':filename, 'contentType':contentType, 'data':data})
return result
security.declareProtected(Workgroup_mailPermission, 'Workgroup_mailFormAction')
def Workgroup_mailFormAction(self, to=None, cc=None, bcc=None, inReplyTo=None,
subject=None, body='', attachments=None, mfrom='',
REQUEST=None):
"""
Sends a message. Many of the input parameters are not currently used,
but can be used for skinning the functionlity.
"""
site_encoding = self._site_encoding()
##################
# Create the message
msg = Message()
msg.set_payload(body, site_encoding)
#####################################
# if attachment, convert to multipart
# file fields are posted even if empty, so we need to remove those :-s
attachments = self._getAttachments(attachments)
if attachments:
mimeMsg = MIMEMultipart()
mimeMsg.attach(msg)
for attachment in attachments:
# Add the attachment
contentType = attachment['contentType']
filename = attachment['filename']
attach_part = Message()
attach_part.add_header('Content-Type', contentType, name=filename)
attach_part.add_header('Content-Disposition', 'attachment', filename=filename)
attach_part.set_payload(attachment['data'])
Encoders.encode_base64(attach_part)
mimeMsg.attach(attach_part)
msg = mimeMsg
########################
# set headers on message
####
# if to is None:
# to = []
# else:
# msg['To'] = ','.join(to)
if cc is None:
cc = []
else:
msg['Cc'] = ','.join(cc)
if bcc is None:
bcc = []
else:
msg['Bcc'] = ','.join(bcc)
# set recepients
if mfrom:
# to.append(mfrom) # send copy to sender
msg['From'] = mfrom
msg['Reply-To'] = mfrom
####
now = self.ZopeTime()
msg['Date'] = now.rfc822() # needed by some servers
if inReplyTo:
msg['In-Reply-To'] = inReplyTo
msg['Subject'] = Header(subject, site_encoding)
##################
# Send the message
SMTPserver = self._mailhost()
success = 0
all_receivers = list(set(bcc))
if all_receivers: # only send if any recipients
for a in all_receivers:
# try:
self._mailhost().send(msg.as_string(), mto=a, mfrom=mfrom)
success = 1
# returns a portal status message
if REQUEST:
if success:
message = 'Succes! The message was sent '
else:
message = 'Error! The message could not be sent'
REQUEST.RESPONSE.redirect(self.absolute_url() + '/Workgroup_mailForm?portal_status_message=%s' % message)
self.saveMessage(to=to, cc=cc, bcc=bcc, inReplyTo=inReplyTo, subject=subject, body=body, attachments=attachments, mfrom=mfrom, date=now,)
######################################
# Email backup
def msgCounterCount(self):
"Returns increments current value and increses it by one"
if not hasattr(self, '_msgCounter'):
# persistentlist to write as little as possible to Data.fs
self._msgCounter = OOBTree({'value':0})
self._msgCounter['value'] += 1
return self._msgCounter['value']
security.declareProtected(View, 'getMessages')
def getMessages(self):
"Returns the message storage"
if not hasattr(self, '_messageStorage'):
self._messageStorage = OOBTree()
return self._messageStorage
security.declareProtected(View, 'getVisibleMessages')
def getVisibleMessages(self, sortkey=None, reverse=0):
"Returns the message storage"
messages = self.getMessages()
wrapped = [OOBTreeWrapper(m) for m in messages.values()]
if sortkey:
decorated = [(o.get(sortkey, None), o) for o in wrapped]
decorated.sort()
sorted = [d[-1] for d in decorated]
if reverse:
sorted.reverse()
return sorted
else:
return wrapped
security.declareProtected(View, 'getMessage')
def getMessage(self, msgId):
"Returns the message storage"
return self.getMessages()[msgId]
security.declareProtected(View, 'getVisibleMessage')
def getVisibleMessage(self, msgId):
"Returns the message storage"
return OOBTreeWrapper(self.getMessage(msgId))
security.declarePublic('html_quote')
def html_quote(self, text):
"Quotes text"
return html_quote(text).replace('\n', '<br />')
security.declareProtected(View, 'saveMessage')
def saveMessage(self, to=None, cc=None, bcc=None, inReplyTo=None,
subject=None, body='', attachments=None, mfrom='', date=None):
"The message is saved in an OOBTree (dict)"
msg = OOBTree()
if to:
msg['to'] = ', '.join(to)
if cc:
msg['cc'] = ', '.join(cc)
if bcc:
msg['bcc'] = ', '.join(bcc)
if inReplyTo:
msg['inReplyTo'] = inReplyTo
if subject:
msg['subject'] = subject
if body:
msg['body'] = body
if attachments:
msg['attachments'] = PersistentList(attachments)
if mfrom:
msg['from'] = mfrom
if date:
msg['date'] = date
id = self.msgCounterCount()
msg['id'] = id
self.getMessages()[id] = msg
security.declarePublic('canDeleteMessages')
def canDeleteMessages(self):
"returns true if current user can delete messages."
mtool = self.portal_membership
member = mtool.getAuthenticatedMember()
return member.has_permission(Workgroup_editPermission, self)
security.declareProtected(Workgroup_editPermission, 'deleteMessages')
def deleteMessages(self, messageIds=None, REQUEST=None):
"Deletes messages"
if messageIds is None:
messageIds = []
messages = self.getMessages()
for id in messageIds:
del messages[id]
if not REQUEST is None:
self_url = self.absolute_url()
psm = 'portal_status_message=%s messages deleted.' % len(messageIds)
REQUEST.RESPONSE.redirect(self_url + '/Workgroup_mailArchive')
security.declarePublic('getAttachmentIconUrl')
def getAttachmentIconUrl(self, attach):
"Returns icon for mimetype"
portal = self.portal_url.getPortalObject()
portal_url = portal.absolute_url()
if hasattr(portal, 'mimetypes_registry'):
mimetypes = portal.mimetypes_registry
matching_types = mimetypes.lookup(attach['contentType'])
if matching_types:
mimetype = matching_types[0]
return '%s/%s' % (portal_url, mimetype.icon_path)
return portal_url + '/file_icon.gif'
security.declareProtected(View, 'downloadAttachment')
def downloadAttachment(self, msgId, attachIdx, REQUEST):
"Returns the attachment"
RESPONSE = REQUEST.RESPONSE
attach = self.getMessage(msgId)['attachments'][attachIdx]
RESPONSE.setHeader('Content-Type', attach['contentType'])
RESPONSE.setHeader('Content-Disposition', 'filename=%s' % attach['filename'])
return attach['data']
--- end listing of EmailMixin.py ---
Cheers,
Zoltan
Replies to this comment