Changeset 1919


Ignore:
Timestamp:
08/08/07 01:48:48 (12 years ago)
Author:
jukka
Message:

Refactored groups to not use portal_groups. Things should be faster and users from weird sources shouldn't cause so much problems. Not much tested yet, but archetype update and quickinstaller reinstall works fine.

Location:
trunk
Files:
5 deleted
19 edited

Legend:

Unmodified
Added
Removed
  • trunk/BlogPost.py

    r1907 r1919  
    3232from permissions import ModerateContent, MODIFY_CONTENT 
    3333from DateTime import DateTime 
    34  
    35 from GroupBlog import monthNames 
    3634 
    3735# Same thing as with MemberFolder but easier: MemberBlogs contain the values of groups itself in indexable storage. 
     
    205203        return 'images/default_member.png' 
    206204 
    207     def myDateToArchive(self): 
    208         # Get year and month 
    209         myresults = [] 
    210         # This function returns array like ['2006', 'October'] for the the current element. 
    211         myCdate = self.CreationDate()[:7] 
    212         myresults = (myCdate.split("-")) 
    213         item = myresults[1] 
    214         if item in monthNames.keys(): 
    215             myresults[1] = monthNames[item] 
    216  
    217         return myresults 
    218  
    219205    def getLatestEditDate(self): 
    220206        """ Returns creation date as blog posts do not have History """ 
  • trunk/ConfigurationMethods.py

    r1907 r1919  
    179179    folder.manage_permission(ADD_CONTENT_PERMISSION, ('Member',), acquire=1) 
    180180 
    181 def setupGroups(self, portal): 
    182     """Set groups to use Blogs as workspaces""" 
    183     grouptool=getToolByName(portal, "portal_groups") 
    184  
    185     if not grouptool.getGroupWorkspacesCreationFlag(): 
    186         grouptool.toggleGroupWorkspacesCreation() 
    187     grouptool.setGroupWorkspacesFolder(id=MEMBERS_FOLDER.lower(), title=MEMBERS_FOLDER) 
    188     grouptool.setGroupWorkspaceType('GroupBlog') 
    189     grouptool.manage_permission('Add Groups', ('Manager','Member'), acquire=1)  
    190     grouptool.manage_permission('Delete Groups', ('Manager','Owner'), acquire=1) 
    191     grouptool.manage_permission('Manage Groups', ('Manager','Owner','Member'), acquire=1) 
    192  
    193181 
    194182def setupMembersFolder(self,portal): 
     
    298286    """Setup custom workflows.""" 
    299287    wtool = getToolByName(portal, 'portal_workflow') 
    300     for workflow in ['group_workflow','lemill_workflow','groupblog_workflow','wikish_workflow','personal_workflow']: 
     288    for workflow in ['group_workflow','lemill_workflow','wikish_workflow','personal_workflow']: 
    301289        try: 
    302290            wtool.manage_delObjects(workflow) 
     
    304292            pass 
    305293    wtool.manage_addWorkflow('group_workflow (LeMill resource workflow)', 'group_workflow') 
    306     wtool.manage_addWorkflow('groupblog_workflow (LeMill group workflow)', 'groupblog_workflow') 
    307294    wtool.manage_addWorkflow('wikish_workflow (LeMill wiki-like workflow)', 'wikish_workflow') 
    308295    wtool.manage_addWorkflow('personal_workflow (LeMill personal workflow)', 'personal_workflow') 
    309296    wtool.setChainForPortalTypes(MATERIAL_TYPES, 'group_workflow') # here LeMillReferences get wrong workflow 
    310     wtool.setChainForPortalTypes(('GroupBlog',), 'groupblog_workflow') 
    311297    wtool.setChainForPortalTypes(('Activity', 'Tool','Piece','LeMillReference'), 'wikish_workflow') # here they get fixed 
    312     wtool.setChainForPortalTypes(('Story', 'MemberFolder', 'BlogPost', 'Collection',), 'personal_workflow') 
     298    wtool.setChainForPortalTypes(('Story', 'MemberFolder', 'BlogPost', 'Collection','GroupBlog'), 'personal_workflow') 
    313299    # Update all resources to have permissions that match the current workflow spec 
    314300    #wtool.updateRoleMappings() 
     
    487473    safeEditProperty(portal, 'validate_email', value=True, data_type="boolean") 
    488474     
    489 def setupRoles(self, portal): 
    490     portal._addRole('CoAuthor') 
    491  
    492  
    493475def setupLeMillFAQ(self, portal): 
    494476    # Create MultimediaMaterial resource lemill-faq based on docs/FAQ.html 
  • trunk/Extensions/Install.py

    r1880 r1919  
    274274                    obj.setSubject_area(new) 
    275275        print >>out, "Migration from 1.11.0 complete" 
    276  
    277  
     276    if doWeMigrate(old,'1.12.0'): 
     277        print >>out, "Starting migration from 1.12.0" 
     278        community=self.community 
     279        groups = community.objectIds('GroupBlog') 
     280        gtool= getToolByName(self, 'portal_groups') 
     281        for gid in groups: 
     282            print gid 
     283            acl_group=gtool.getGroupById(gid) 
     284            groupblog=community.getGroupById(gid) 
     285            if not acl_group: 
     286                print 'Missing acl_group: %s' % gid 
     287            for m in acl_group.getGroupMembers(): 
     288                mid=m.getId() 
     289                groupblog.addMember(mid) 
     290                self.acl_users.source_groups.removePrincipalFromGroup(mid, gid) 
     291            if acl_group.getGroupMembers(): 
     292                print acl_group.getGroupMembers() 
     293            else: 
     294                gtool.removeGroups([gid], keep_workspaces=1) 
     295    if doWeMigrate(old,'1.12.1'): 
     296        print >>out, "Starting migration from 1.12.1" 
     297        community=self.community 
     298        for obj in self.content.objectValues(('MultimediaMaterial','PILOTMaterial', 'PresentationMaterial')): 
     299            gid=obj.getGroupsShared() 
     300            print gid 
     301            print obj.id 
     302            if gid and gid!='no_group': 
     303                try: 
     304                    group=community.getGroupById(gid) 
     305                except: 
     306                    group=None 
     307                if group: 
     308                    obj.setGroupEditing(group.UID()) 
     309             
    278310 
    279311def uninstall(self): 
  • trunk/GroupBlog.py

    r1876 r1919  
    4040 
    4141import time 
    42  
    43 monthNames = {'01':'month_jan', '02':'month_feb', '03':'month_mar', '04':'month_apr', '05':'month_may', '06':'month_jun', '07':'month_jul', '08':'month_aug', '09':'month_sep', '10':'month_oct', '11':'month_nov', '12':'month_dec'} 
    4442 
    4543# Same thing as with MemberFolder but easier: MemberBlogs contain the values of groups itself in indexable storage. 
     
    7977            ) 
    8078        ), 
    81     LinesField('recent_activity', 
    82         default= [], 
     79    LinesField('groupMembers', 
     80        default=[], 
     81        index = 'KeywordIndex:schema', 
    8382        widget = LinesWidget( 
    8483            visible = {'view':'invisible', 'edit':'invisible'}, 
     
    8685        ), 
    8786 
    88     LinesField('moderators', 
    89         default = [], 
    90         vocabulary = 'getMembersList', 
    91         widget = PicklistWidget(             
    92              label = 'Moderators', 
    93              label_msgid = 'label_group_moderators', 
    94              description = "Trusted members of group can help you to remove offensive posts and keep the group together.", 
    95              description_msgid = 'help_group_moderators', 
    96              i18n_domain = "lemill", 
    97              visible = {'view':'invisible', 'edit':'visible'}, 
    98              ) 
    99         ),         
    100  
    101  
    102     TagsField('banned', 
    103         default=[], 
    104         widget = TagsWidget( 
    105             label = 'Ban members', 
    106             label_msgid = 'label_ban_members', 
    107             description = "If someone repeatedly offends against group, group founder can ban him and prevent from joining the group again. Separate user id's with commas. User id's can be found by going to offending members member page and noticing the address in the browser. Id is the last part of address, after /community/.", 
    108             descriptio_msgid = 'help_ban_members', 
    109             i18n_domain = "lemill", 
    110             visible = {'view':'invisible', 'edit':'invisible'}, 
    111             ), 
    112         ), 
    113 )) 
     87 )) 
    11488 
    11589schema = schema.copy() 
     
    175149        mtool = getToolByName(self, 'portal_membership') 
    176150        memberfolder=mtool.getHomeFolder() 
    177         me = mtool.getAuthenticatedMember() 
    178151        if memberfolder!=None and type(memberfolder)=='MemberFolder': 
    179             memberfolder.note_action(item.UID(), item.portal_type, 'afterAdd') 
    180         self.content_status_modify(workflow_action='publish', msg='silent') 
     152            memberfolder.recalculateScore() 
    181153        if not hasattr(item.aq_base, 'left_slots'): 
    182154            self._setProperty('left_slots', ['here/portlet_%s_actions/macros/portlet' % item.meta_type.lower(),], 'lines') 
     
    193165    def at_post_edit_script(self): 
    194166        mtool = getToolByName(self, 'portal_membership') 
    195         ltool = getToolByName(self, 'lemill_tool') 
    196167        memberfolder=mtool.getHomeFolder() 
    197168        if memberfolder!=None: 
    198169            memberfolder.note_action(self.UID(), self.portal_type, 'post_edit') 
    199  
    200170        self.recalculateScore() 
    201         if hasattr(ltool,'allow_banning'): 
    202             if ltool.allow_banning: 
    203                 if self.getField('banned').widget.visible['edit']!='visible': 
    204                     self.getField('banned').widget.visible['edit']='visible' 
    205             else: 
    206                 if self.getField('banned').widget.visible['edit']!='invisible': 
    207                     self.getField('banned').widget.visible['edit']='invisible' 
    208  
    209  
    210     def setMeAsOwner(self): 
    211         mtool = getToolByName(self, 'portal_membership') 
    212         me = mtool.getAuthenticatedMember() 
    213         if [self.getId()] == self.users_with_local_role('Owner'): 
    214             self.manage_setLocalRoles(me.getId(), ['Owner']) 
    215             self.manage_addLocalRoles(me.getId(), ['Reviewer']) 
    216             #print self.users_with_local_role('Owner') 
    217171             
    218  
    219172    def getGroupMaterials(self, n=False): 
    220         """ Get resources used by group, uses portfolio-topic """ 
    221         results=self.portfolio.queryCatalog(getGroupsShared=self.getId())  
     173        """ Get resources edited by this group """ 
     174        pc=getToolByName(self, 'portal_catalog')         
     175        results=pc({'getRawGroupEditing':self.UID()}) 
    222176        if n: 
    223177            return len(results) 
    224         return results 
     178        else: 
     179            return results 
     180 
     181    def getGroupMembersNamesAndUrls(self): 
     182        memberids= self.getGroupMembers() 
     183        reslist=[] 
     184        for mid in memberids: 
     185            memberfolder=self.getMemberFolderById(mid) 
     186            if memberfolder: 
     187                reslist.append((memberfolder.NiceName(), memberfolder.absolute_url())) 
     188        return reslist 
    225189 
    226190    def getLatestEditDate(self): 
     
    230194    def getSamples(self): 
    231195        """ get n number of samples """ 
    232         q = {'review_state':'public', 'meta_type': self.getFeaturedTypes(), 'getHasCoverImage':True, 'getGroupsShared': self.getId()} 
    233         all = self.portfolio.queryCatalog(q) 
     196        all = self.getGroupMaterials() 
     197        all = [a for a in all if a.review_state=='public' and a.portal_type in self.getFeaturedTypes() and a.getHasCoverImage==True]  
    234198        import random 
    235199        n = min(3, len(all)) 
    236200        return random.sample(all,n) 
    237  
    238  
    239  
    240     def prefill_title(self): 
    241         # When GroupBlog is created we need to get same values as group itself here 
    242         # It seems that the marching order in creating a group sets these to 'x:s workspace' after creating object. 
    243         groupid = self.getId() 
    244         grouptool = getToolByName(self, 'portal_groups') 
    245         group=grouptool.getGroupById(groupid) 
    246         value= group.getTitle() 
    247         return value 
    248  
    249     def prefill_description(self): 
    250         # When GroupBlog is created we need to get same values as group itself here 
    251         groupid = self.getId() 
    252         grouptool = getToolByName(self, 'portal_groups') 
    253         group=grouptool.getGroupById(groupid) 
    254         value= group.getDescription() 
    255         return value 
    256201 
    257202    def getCoverImageURL(self, drafts=False): 
     
    262207        return 'images/default_group.png'  
    263208         
    264     def amIOwner(self): 
    265         """ check owner of object """ 
    266         roles = self.portal_membership.getAuthenticatedMember().getRolesInContext(self) 
    267         return 'Owner' in roles 
    268  
    269209    def isPost(self): 
    270         return False 
    271  
    272     def getMembersList(self, no_self=True): 
    273         groupid = self.getId() 
    274         grouptool = getToolByName(self, 'portal_groups') 
    275         usertool = getToolByName(self, 'lemill_usertool') 
    276         group=grouptool.getGroupById(groupid) 
    277         if no_self: 
    278             dll = [usertool.getLeMillMemberFolder(y.getId()) for y in group.getGroupMembers() if y.getId()!=self.Creator()] 
    279         else: 
    280             dll = [usertool.getLeMillMemberFolder(y.getId()) for y in group.getGroupMembers()] 
    281         dl = [(x.getId(), x.NiceName()) for x in dll] 
    282         return DisplayList(dl) 
    283  
    284     def getGroupMembers(self): 
    285         """ Public access to memberlist, returns tuple where (nicename, role, url) """ 
    286         groupid = self.getId() 
    287         grouptool = getToolByName(self, 'portal_groups') 
    288         usertool = getToolByName(self, 'lemill_usertool') 
    289         group=grouptool.getGroupById(groupid) 
    290         if group: 
    291             dll = [usertool.getLeMillMemberFolder(y.getId()) for y in group.getGroupMembers()] 
    292             return [(x.NiceName(), self.get_local_roles_for_userid(x.getId()),x.absolute_url()) for x in dll if dll] 
    293             return [] 
    294         else: 
    295             return [] 
    296          
     210        return False         
    297211         
    298212    def NiceName(self): 
     
    305219 
    306220    def isMember(self, memberid): 
    307         groupid = self.getId() 
    308         grouptool = getToolByName(self, 'portal_groups') 
    309         group=grouptool.getGroupById(groupid) 
    310         return memberid in [x.getId() for x in group.getGroupMembers()] 
    311  
     221        return memberid in self.getGroupMembers() 
    312222 
    313223    def canIModerate(self): 
    314         roles = self.getRoles() 
     224        roles = self.portal_membership.getAuthenticatedMember().getRolesInContext(self) 
    315225        return 'Manager' in roles or 'Reviewer' in roles 
    316  
    317  
    318     def getRoles(self, memberid=None): 
    319         # Helper method to get roles 
    320         if memberid: 
    321             return self.get_local_roles_for_userid(memberid) 
    322         else: 
    323             mtool = getToolByName(self, 'portal_membership') 
    324             user = mtool.getAuthenticatedMember()         
    325             return self.get_local_roles_for_userid(user.getId()) 
    326226         
    327227    def getPosts(self, batch=True, b_size=30, b_start=0): 
     
    354254    def getBlog(self): 
    355255        return self 
    356  
    357     def getRecent_activity(self): 
    358         """ Because I prefer lists, not tuples """ 
    359         return list(self.getField('recent_activity').get(self)) 
    360  
    361     security.declareProtected(MODIFY_CONTENT,'addRecent_activity') 
    362     def addRecent_activity(self, obj_uid, act_type): 
    363         """ Recent activity is a list of (obj_UID, date, activity type {'modified piece', 'created' etc.}) 
    364          that tracks member activities for all kinds of calculations """ 
    365  
    366         current_date = DateTime() 
    367         acts= self.getRecent_activity() 
    368         acts=[(obj_uid,current_date,act_type)]+acts 
    369         # pop out old collaboration proposals from tail of the list 
    370         while acts[-1][1] < (current_date-31): 
    371             acts.pop() 
    372         acts_field=self.getField('recent_activity') 
    373         acts_field.set(self, acts) 
    374256         
    375257    security.declareProtected(MODIFY_CONTENT,'addRecent_post') 
     
    398280        self.setRecent_posts(postlist)             
    399281 
    400     def do_joining(self, userid, groupid): 
    401         try: 
    402             self.acl_users.source_groups.addPrincipalToGroup(userid, groupid) 
    403         except: 
    404             return 1 
    405         return 0 
    406  
    407          
    408     def do_leaving(self, userid, groupid): 
    409         try: 
    410             self.acl_users.source_groups.removePrincipalFromGroup(userid, groupid) 
    411             if len(self.getGroupMembers()) <= 0: 
    412                 for x in self.getGroupMaterials(): 
    413                     x.getObject().setGroupsShared('no_group') 
    414                 groupTool = getToolByName(self, 'portal_groups') 
    415                 groupTool.removeGroups([self.getId()]) 
    416         except: 
    417             return 1 
    418         return 0 
     282#    def do_joining(self, userid, groupid): 
     283#        try: 
     284#            self.acl_users.source_groups.addPrincipalToGroup(userid, groupid) 
     285#        except: 
     286#            return 1 
     287#        return 0 
     288# 
     289#         
     290#    def do_leaving(self, userid, groupid): 
     291#        try: 
     292#            self.acl_users.source_groups.removePrincipalFromGroup(userid, groupid) 
     293#            if len(self.getGroupMembers()) <= 0: 
     294#                for x in self.getGroupMaterials(): 
     295#                    x.getObject().setGroupsShared('no_group') 
     296#                groupTool = getToolByName(self, 'portal_groups') 
     297#                groupTool.removeGroups([self.getId()]) 
     298#        except: 
     299#            return 1 
     300#        return 0 
     301 
     302 
     303    def addMember(self, memberid): 
     304        mtool = getToolByName(self, 'portal_membership') 
     305        memberfolder=mtool.getHomeFolder(memberid) 
     306        if not memberfolder: 
     307            print "We have a problem: %s cannot be found and is not added to group" % memberid 
     308            return False 
     309        mid=memberfolder.getMemberId() 
     310        users=list(self.getGroupMembers()) 
     311        if mid in users: 
     312            return False 
     313        self.setGroupMembers(users+[mid]) 
     314        return True 
     315             
     316    def removeMember(self, memberid): 
     317        mtool = getToolByName(self, 'portal_membership') 
     318        memberfolder=mtool.getHomeFolder(memberid) 
     319        if memberfolder: 
     320            mid=memberfolder.getMemberId() 
     321        else: 
     322            print "We have a problem: %s cannot be found. removing him from group anyway" % memberid 
     323            mid=memberid 
     324        users=list(self.getGroupMembers()) 
     325        if mid not in users: 
     326            return False 
     327        users=users.remove(mid) 
     328        self.setGroupMembers(users) 
     329        return True      
     330         
     331         
    419332             
    420333    def join_group(self): 
     
    425338        user = mtool.getAuthenticatedMember()         
    426339        userid = user.getId() 
    427         groupid = self.getId() 
    428         banned=self.getField('banned').get(self)         
    429         if userid in banned: 
    430             putils.addPortalMessage( _(u"You have been banned from this group and cannot join anymore.")) 
    431             return REQUEST.RESPONSE.redirect(self.community.absolute_url()) 
    432          
    433         join_res = 0 
    434         join_res = self.do_joining(userid, groupid) 
    435         if not join_res: 
     340        if self.addMember(userid): 
    436341            msg = _("You have joined the group '${title}'.", mapping={u'title' : self.title_or_id()}) 
    437342        else: 
    438             msg= _(u"Joining the group failed for some reason.") 
     343            msg= _(u"You are already member in this group.") 
    439344        putils.addPortalMessage(msg) 
    440345        return REQUEST.RESPONSE.redirect(self.absolute_url()) 
     
    447352        user = mtool.getAuthenticatedMember() 
    448353        userid = user.getId() 
    449         groupid = self.getId() 
    450         leave_res = 0 
    451         leave_res = self.do_leaving(userid, groupid) 
    452         if not leave_res: 
     354        if self.removeMember(userid): 
    453355            msg = _("You have left the group '${title}'.", mapping={u'title' : self.title_or_id()}) 
    454356        else: 
    455             msg= _(u"Leaving the group failed for some reason.") 
     357            msg= _(u"You are not member in this group.") 
    456358        putils.addPortalMessage(msg) 
    457359        return REQUEST.RESPONSE.redirect(self.community.absolute_url()) 
    458360 
    459  
    460 ### Mutators = default mutator + set group properties 
    461  
    462      
    463     security.declareProtected(MODIFY_CONTENT,'setProperties') 
    464     def setProperties(self, newprops=None, **kw): 
    465         """ Try to get mutator for each value and if there isn't one then change groups properties """ 
    466         if newprops is None: 
    467             newprops = kw 
    468         grouptool = getToolByName(self, 'portal_groups') 
    469         groupid=self.getId() 
    470         #print groupid +' changes properties:' + str(newprops) 
    471         for (key, value) in newprops.items(): 
    472             accessor='get'+str(key.capitalize()) 
    473             mutator='set'+str(key.capitalize()) 
    474  
    475             if hasattr(self, accessor): 
    476                 if eval('self.'+accessor+'()') != value: 
    477                     eval('self.'+mutator+'(value)') 
    478                     #print 'changing attribute with self.'+mutator+'(value), value='+str(value) 
    479                 else: 
    480                     group=grouptool.getGroupById(groupid) 
    481                     group.setProperties({key:value}) 
    482         self.reindexObject()          
    483  
    484     def setModerators(self, value, **kwargs): 
    485         field=self.getField('moderators') 
    486         old_mods=field.get(self) 
    487         if old_mods==None or old_mods=='' or old_mods==['']: old_mods=[] 
    488         if value==None or value=='' or value==['']: value=[] 
    489         additions= [x for x in value if x not in old_mods] 
    490         for member in additions: 
    491             if member != '': 
    492                 self.manage_setLocalRoles(member,['Reviewer']) 
    493         removals= [x for x in old_mods if x not in value] 
    494         for member in removals: 
    495             if 'Owner' not in self.get_local_roles_for_userid(member): 
    496                 self.manage_delLocalRoles(member)             
    497         field.set(self, value, **kwargs) 
    498          
    499     def setBanned(self, value, **kwargs): 
    500         field=self.getField('banned') 
    501         if type(value)==list or type(value)==tuple: 
    502             banlist=list(value) 
    503         else: 
    504             banlist= [x.strip() for x in value.split(',')] 
    505         if banlist==['']: banlist=[] 
    506         grouptool = getToolByName(self, 'portal_groups') 
    507         groupid=self.getId() 
    508         group=grouptool.getGroupById(groupid) 
    509         groupmembers= group.getGroupMemberIds() 
    510         those_who_need_a_kick= [x for x in banlist if x in groupmembers] 
    511         for kickee in those_who_need_a_kick:             
    512             if 'Owner' not in self.get_local_roles_for_userid(kickee): # can't kick yourself 
    513                 self.manage_delLocalRoles(kickee)                         
    514                 self.do_leaving(kickee, groupid) # kick! 
    515         field.set(self, value, **kwargs) 
     361  
    516362         
    517363 
     
    536382        self.reindexObject() 
    537383 
    538     def getArchDates(self): 
    539         """ Get years for Archives  """ 
    540         dates = [] 
    541         # The result should be something like this (but in reverse sorted order): 
    542         #['2006-10', '2006-01', '2007-11', '2006-07', '2007-04', '2007-02'] 
    543         results = self.objectValues('BlogPost') 
    544         for x in results: 
    545             cDate = x.CreationDate()[:7] 
    546             if cDate not in dates: 
    547                 dates.append(cDate) 
    548         dates.sort() 
    549         dates.reverse() 
    550          
    551         return dates 
    552  
    553  
    554     def interpritArchDates(self): 
    555         """ Interprit arch Dates given  """ 
    556         preresults = [] 
    557         results = [] 
    558         # This function splits the dates array elements by '-' in 2. And changes the code of the month by its name. 
    559         gotDates = self.getArchDates() 
    560         for y in gotDates: 
    561             preresults.append(y.split("-")) 
    562         for z in preresults: 
    563             item = z[1] 
    564             if item in monthNames.keys(): 
    565                 z[1] = monthNames[item] 
    566                 results.append(z) 
    567          
    568         return results 
    569384 
    570385    def recalculateScore(self): 
  • trunk/LargeSectionFolder.py

    r1915 r1919  
    480480                return DEFAULT_ICONS['Piece'] 
    481481 
    482     def getTitleOfACLGroup(self, group): 
    483         """ gfjreih5eh """ 
    484         return getToolByName(self, 'portal_groups').getGroupareaFolder(group.getId()).title_or_id() 
    485  
    486  
    487482    security.declareProtected(MANAGE_PORTAL, 'recalculate_all_scores') 
    488483    def recalculate_all_scores(self, REQUEST=None): 
     
    868863        return folder.absolute_url()    
    869864 
     865    def getMemberFolderById(self,id): 
     866        """ sometimes it is easier to just get it directly from btreefolder """ 
     867        return getattr(self, id, None) 
     868 
     869    def getGroupById(self,id): 
     870        """ sometimes it is easier to just get it directly from btreefolder """ 
     871        return getattr(self, id, None) 
     872 
     873 
     874 
    870875    def mergeLatestPostsInMyGroups(self): 
    871876        mtool = getToolByName(self, "portal_membership") 
    872         gtool = getToolByName(self, "portal_groups") 
    873         member=mtool.getAuthenticatedMember() 
    874         memberid=member.getId() 
    875         glist = self.lemill_usertool.getGroupsList(memberid); 
     877        memberfolder=mtool.getHomeFolder() 
     878        glist=memberfolder.getGroups(objects=True) 
    876879        recents=[] 
    877880        for group in glist: 
    878             gname= group.getGroupName() 
    879             garea= gtool.getGroupareaFolder(gname) 
    880             grecent= garea.getRecent_posts() 
     881            grecent= group.getRecent_posts() 
    881882            for postid in grecent: 
    882883                try: 
    883                     post=garea._getOb(postid) 
     884                    post=group._getOb(postid) 
    884885                    recents.append((post.CreationDate(),post)) 
    885886                except AttributeError: 
    886887                    # do some cleaning: 
    887                     garea.removeRecent_post(postid) 
     888                    group.removeRecent_post(postid) 
    888889        recents.sort() 
    889890        recents = [x[1] for x in recents] 
  • trunk/LeMillTool.py

    r1905 r1919  
    5959    security.declarePublic('createUniqueGroupId') 
    6060    def createUniqueGroupId(self, basename): 
    61         #Groups should always use titles for display, but urls use ids so lets make ids understandable & unique. 
    62         # basename should be user's id or material's id, we add _group+numbers after that.  
     61        #Groups should always use titles for display, but we have to start from something 
    6362        basename=str(basename) 
    64         grouptool=getToolByName(self, 'portal_groups') 
    65         folder=grouptool.getGroupWorkspacesFolder() 
    6663        name=basename+'_group' 
    6764        number=1 
    68         while name in folder.objectIds(): 
     65        folder=self.community 
     66        while hasattr(folder, name): 
    6967            name=basename+'_group'+str(number) 
    7068            number=number+1 
  • trunk/LeMillUserTool.py

    r1762 r1919  
    4444    def getPortraitURL(self,author): 
    4545        return getattr(self.community,author).getPortraitURL() 
    46      
    47     # Group-related methods. Mostly to provide checks that the user is not zope root's admin before trying to find his groups roles. 
    48          
    49     security.declarePublic('getGroupsList') 
    50     def getGroupsList(self, userid): 
    51         # for user vahur getUser(userid) returned user VahurRebas . 
    52         # getUserById returns correct user 
    53         user = self.acl_users.getUserById(userid) 
    54         groupstool = getToolByName(self, 'portal_groups') 
    55         # Check if user is capable of having groups. 
    56         if not hasattr(user, '_groups') or not user: 
    57             #print 'no groups for this guy ' 
    58             return [] 
    59         # Then we can let GRUF do its things 
    60         #print 'trying to get groups for '    
    61         if user.getUserName() != userid: 
    62             # Interesting bug that when user vahur isn't in GroupUserFolder but Vahur is, then Vahur is returned 
    63             # and sees other user's groups as his own. 
    64             return [] 
    65         # getGroupsByUserId(userid) uses getUser(userid) which returns wrong user. 
    66         # return groupstool.getGroupsByUserId(userid)     
    67         groups = user.getGroups() or [] 
    68         return [groupstool.getGroupById(elt) for elt in groups] 
    69          
    70          
    71     security.declareProtected(AddGroups, 'setGroupProperties') 
    72     def setGroupProperties(self, group, mapping): 
    73         '''Sets the properties of the group with a bit more allowing permissions (original requires manage_users). 
    74         ''' 
    75         group.setGroupProperties(mapping) 
    76          
    77     security.declareProtected(ViewGroups, 'listOwnedMaterial') 
    78     def listOwnedMaterial(self, group): 
    79         '''Returns a list of entries in catalog metadata format like searches usually do''' 
    80          
    81     #FIXME: permissions not thought through yet 
    82     security.declareProtected(AddGroups, 'setLeMillOwnership') 
    83     def setLeMillOwnership(self, group, object): 
    84         """Sets group as an owner for an object and add object's id to groups list""" 
    85         groupstool = getToolByName(self, 'portal_groups') 
    86         groupstool.setGroupOwnership(self, group, object) 
    87         # something like this: 
    88         # owned= group.getProperty(ownedlist) 
    89         # owned.append(self.zodbid) 
    90         # group.setProperty(ownedlist=owned)  
    91         # return success 
    92          
    93     #def joinEdit(self, group, object): 
    94  
     46                             
    9547    def getLeMillMemberId(self): 
    9648        """ Returns the username of the portal member. """ 
  • trunk/LeMillWorkflow.py

    r1785 r1919  
    3434    return ob 
    3535 
    36 def createGroupBlog_workflow(id): 
    37     """ create workflow """ 
    38     ob = DCWorkflowDefinition(id) 
    39     setupGroupBlog_workflow(ob) 
    40     #setupScripts(ob) 
    41     return ob 
    42  
    4336def createWikish_workflow(id): 
    4437    """ create workflow """ 
     
    5649 
    5750 
    58 # This really is resource workflow, but if we change the id, other workflows that inherit from this are rebuilt in such way the lose their wf state. 
     51# This really is resource workflow, but if we change the id, other workflows that inherit from this are rebuilt in such way that they lose their wf state. 
    5952 
    6053def setupGroup_workflow(wf): 
     
    7871    state = wf.states['draft'] 
    7972    state.setProperties(title='draft', transitions=('publish','delete')) 
    80     state.setPermission(view, 0, ('Manager', 'Owner', 'CoAuthor', 'Member', 'Authenticated', 'Anonymous')) 
    81     state.setPermission(edit, 0, ('Manager', 'Owner', 'CoAuthor', 'Member')) 
     73    state.setPermission(view, 0, ('Manager', 'Owner', 'Member', 'Authenticated', 'Anonymous')) 
     74    state.setPermission(edit, 0, ('Manager', 'Owner', 'Member')) 
    8275    state.setPermission(delete, 0, ('Manager', 'Reviewer', 'Owner')) 
    83     state.setPermission(access, 0, ('Manager', 'Owner', 'CoAuthor', 'Member', 'Authenticated', 'Anonymous')) 
     76    state.setPermission(access, 0, ('Manager', 'Owner', 'Member', 'Authenticated', 'Anonymous')) 
    8477 
    8578    state = wf.states['public'] 
    8679    state.setProperties(title='published', transitions=('retract','delete')) 
    87     state.setPermission(view, 0, ('Manager', 'Owner', 'CoAuthor', 'Member', 'Authenticated', 'Anonymous')) 
    88     state.setPermission(edit, 0, ('Manager', 'Owner', 'CoAuthor', 'Member')) 
     80    state.setPermission(view, 0, ('Manager', 'Owner', 'Member', 'Authenticated', 'Anonymous')) 
     81    state.setPermission(edit, 0, ('Manager', 'Owner', 'Member')) 
    8982    state.setPermission(delete, 0, ('Manager', 'Reviewer', 'Owner')) 
    90     state.setPermission(access, 0, ('Manager', 'Reviewer', 'Owner', 'CoAuthor', 'Member', 'Authenticated', 'Anonymous')) 
     83    state.setPermission(access, 0, ('Manager', 'Reviewer', 'Owner', 'Member', 'Authenticated', 'Anonymous')) 
    9184 
    9285    state = wf.states['deleted'] 
    9386    state.setProperties(title='deleted', transitions=('restore','publish')) 
    94     state.setPermission(view, 0, ('Manager', 'Reviewer', 'Owner', 'CoAuthor', 'Member', 'Authenticated', 'Anonymous')) 
    95     state.setPermission(edit, 0, ('Manager', 'Owner', 'CoAuthor', 'Member')) 
     87    state.setPermission(view, 0, ('Manager', 'Reviewer', 'Owner', 'Member', 'Authenticated', 'Anonymous')) 
     88    state.setPermission(edit, 0, ('Manager', 'Owner', 'Member')) 
    9689    state.setPermission(delete, 0, ('Manager', 'Reviewer', 'Owner')) 
    97     state.setPermission(access, 0, ('Manager', 'Owner', 'CoAuthor', 'Member', 'Authenticated', 'Anonymous')) 
     90    state.setPermission(access, 0, ('Manager', 'Owner', 'Member', 'Authenticated', 'Anonymous')) 
    9891     
    9992    # transitions  
     
    164157            for_status=1, update_always=1) 
    165158 
    166  
    167 def setupGroupBlog_workflow(wf): 
    168     # Get defaults from here: 
    169     setupGroup_workflow(wf) 
    170  
    171     wf.setProperties(title='LeMill Group Workflow') 
    172  
    173     # Don't need draft state - just public and hidden 
    174     wf.states.deleteStates(('draft',)) 
    175     wf.states.setInitialState('public') 
    176     wf.transitions.deleteTransitions(('retract','restore')) 
    177     state=wf.states['public'] 
    178     state.setPermission(edit, 0, ('Manager', 'Owner', 'CoAuthor')) 
    179159 
    180160 
     
    200180    # Add edit access to all members 
    201181    state=wf.states['public'] 
    202     state.setPermission(edit, 0, ('Manager', 'Owner', 'CoAuthor', 'Member')) 
     182    state.setPermission(edit, 0, ('Manager', 'Owner', 'Member')) 
    203183 
    204184addWorkflowFactory(createGroup_workflow, 
    205185        id='group_workflow', 
    206186        title='LeMill resource workflow') 
    207  
    208 addWorkflowFactory(createGroupBlog_workflow, 
    209         id='groupblog_workflow', 
    210         title='LeMill group workflow') 
    211187 
    212188addWorkflowFactory(createWikish_workflow, 
  • trunk/MemberFolder.py

    r1886 r1919  
    219219        ), 
    220220 
    221     LinesField('recent_activity', 
    222         default= [], 
    223         widget = LinesWidget( 
    224             visible = {'view':'invisible', 'edit':'invisible'}, 
    225             ), 
    226         ), 
    227  
    228221    TextField('biography', 
    229222        searchable = True, 
     
    367360        return (self.collections, msg)       
    368361     
    369     def whatamI(self): 
    370         # Because my dynamically created methods confuse my author 
    371         #print dir(self) 
    372         return dir(self)         
    373  
    374362    def getCountrylist(self): 
    375363        """ We don't need short country codes, so we make a list where fancyname=fancyname and give that as DisplayList """ 
     
    520508 
    521509 
    522     def getGroups(self): 
     510    def getGroups(self, objects=False): 
    523511        """ Gets groups where member belongs""" 
    524         userobj = self.acl_users.getUserById(self.Creator()) 
    525         return userobj.getGroups() or [] 
     512        pc=getToolByName(self, 'portal_catalog') 
     513        objlist=pc({'getGroupMembers':self.getMemberId(), 'portal_type':'GroupBlog'}) 
     514        if objects: 
     515            return [o.getObject() for o in objlist] 
     516        else: 
     517            return objlist 
    526518 
    527519 
    528520    def getSamples(self): 
    529521        """ get n number of samples """ 
    530         all_contents = self.portfolio.queryCatalog({'review_state':'public', 'meta_type': self.getFeaturedTypes(), 'getHasCoverImage':True, 'Creator': self.getMemberFolder().Creator()}) 
     522        my_id=self.getMemberId() 
     523        all_contents = self.portfolio.queryCatalog({'review_state':'public', 'meta_type': self.getFeaturedTypes(), 'getHasCoverImage':True, 'Creator': my_id}) 
    531524  
    532525        if len(all_contents) >= 3: 
    533526            return random.sample(all_contents,3) 
    534527        else: 
    535             all_pieces = self.portfolio.queryCatalog({'review_state':'public', 'meta_type': ('Piece',), 'getHasCoverImage':True, 'Creator': self.getMemberFolder().Creator()}) 
     528            all_pieces = self.portfolio.queryCatalog({'review_state':'public', 'meta_type': ('Piece',), 'getHasCoverImage':True, 'Creator': my_id}) 
    536529            return list(all_contents) + random.sample(all_pieces,min(len(all_pieces), 3-len(all_contents))) 
    537530         
    538  
    539     def note_action(self, obj_uid, portal_type, sender): 
    540         """ Calculate activity score and add to recent activities """         
    541         acts=self.getRecent_activity() 
    542         uids=[x[0] for x in acts] 
    543         score=self.getScore() 
    544         if score==None: score=0 
    545         if sender=='post_edit': 
    546             msg='Modify %s' % portal_type 
    547         elif sender=='afterAdd': 
    548             msg='Create %s' % portal_type             
    549         else: 
    550             msg='?? %s' % portal_type 
    551          
    552         if not obj_uid in uids: 
    553             if sender=='afterAdd': 
    554                 if portal_type=='Piece' or portal_type=='GroupBlog': 
    555                     score=score+3 
    556                 elif 'Material' in portal_type or portal_type=='Activity' or portal_type=='Tool': 
    557                     score=score+5 
    558                 elif portal_type=='BlogPost': 
    559                     score=score+2         
    560             if sender=='post_edit': 
    561                 if 'Material' in portal_type or portal_type=='Activity' or portal_type=='Tool': 
    562                     score=score+5            
    563             self.setScore(score) 
    564             self.reindexObject() 
    565         self.addRecent_activity(obj_uid, msg) 
    566  
    567     def getRecent_activity(self): 
    568         """ Linesfield stores tuple of strings and we need list of tuples. So... """ 
    569         src=list(self.getField('recent_activity').get(self)) 
    570         return [tuple(x.split(',')) for x in src] 
    571          
    572          
    573     def addRecent_activity(self, obj_uid, act_type): 
    574         """ Recent activity is a list of (obj_UID, date, activity type {'modified piece', 'created' etc.}) 
    575          that tracks member activities for all kinds of calculations """ 
    576  
    577         current_date = DateTime() 
    578         acts= self.getRecent_activity() 
    579         acts=[(obj_uid,current_date,act_type)]+acts 
    580         # pop out old collaboration proposals from tail of the list 
    581         while acts[-1][1] < (current_date-31): 
    582             acts.pop() 
    583         acts=[','.join((obj_uid, str(current_date), act_type)) for (obj_uid,current_date,act_type) in acts] 
    584         acts_field=self.getField('recent_activity') 
    585         acts_field.set(self, acts) 
    586531 
    587532    def getDefaultIcon(self, meta_type='', obj=None): 
  • trunk/Resources.py

    r1908 r1919  
    205205        except TypeError: 
    206206            pass # ZEXP import problem 
    207         mtool = getToolByName(self, 'portal_membership') 
    208         memberfolder=mtool.getHomeFolder() 
    209         if memberfolder!=None: 
    210             try: 
    211                 memberfolder.note_action(item.UID(), item.portal_type, 'afterAdd') 
    212             except AttributeError: 
    213                 pass # this happens when importing objects from ZEXP files 
    214207        if not hasattr(item.aq_base, 'left_slots'): 
    215208            self._setProperty('left_slots', ['here/portlet_%s_actions/macros/portlet' % item.meta_type.lower(),], 'lines') 
     
    234227        memberfolder=mtool.getHomeFolder() 
    235228        if memberfolder!=None: 
    236             memberfolder.note_action(self.UID(), self.portal_type, 'post_edit') 
     229            memberfolder.recalculateScore() 
    237230 
    238231    security.declarePrivate('post_edit_rename') 
     
    346339    def getUserGroups(self, allow_none=True): 
    347340        """ this is vocabulary for groups field """ 
    348         req = self.REQUEST 
    349         ut = getToolByName(self, 'lemill_usertool') 
    350         groups = ut.getGroupsList(str(req.AUTHENTICATED_USER)) 
     341        mtool = getToolByName(self, 'portal_membership') 
     342        memberfolder=mtool.getHomeFolder() 
     343        groups=memberfolder.getGroups() 
     344 
    351345        if allow_none: 
    352346            mess_not_assigned = _(u'Not assigned to any group') 
     
    354348        else: 
    355349            result = [] 
    356         if groups: 
    357             pg = getToolByName(self, 'portal_groups') 
    358             for g in groups: 
    359                 group_id = g.getGroupId() 
    360                 ga = pg.getGroupareaFolder(group_id) 
    361                 result.append((group_id, ga.TitleOrId())) 
     350        for g in groups: 
     351            result.append((g.UID, g.Title)) 
    362352        mess_create_new_group = _(u'...or create a new group:') 
    363353        result.append(('__new_group', mess_create_new_group)) 
     
    437427 
    438428 
     429    def review_state(self): 
     430        """ shortcut to portal_workflow's review state """ 
     431        wtool = getToolByName(self, 'portal_workflow') 
     432        return wtool.getInfoFor(self,'review_state',None)     
     433 
    439434    security.declareProtected(MANAGE_PORTAL, 'permaDelete') 
    440435    def permaDelete(self, REQUEST): 
    441436        """Move to trash""" 
    442         portal_workflow=getToolByName(self, 'portal_workflow') 
    443         if not portal_workflow.getInfoFor(self,'review_state',None) == 'deleted': 
     437        if not self.review_state() == 'deleted': 
    444438            return self 
    445439        portal_url = getToolByName(self, 'portal_url') 
     
    804798        creators=creators_field.get(self) 
    805799 
    806         if getToolByName(self,'portal_workflow').getInfoFor(self,'review_state',None) == 'draft': 
     800        if self.review_state() == 'draft': 
    807801            #print 'draft' 
    808802            return creators 
     
    921915            has_cover.set(self,False) 
    922916 
    923     def getGroupsEditing(self): 
    924         """ return a list of groups that are this editing material """ 
    925         local_roles = self.get_local_roles() 
    926         grouptool = getToolByName(self, 'portal_groups') 
    927         groups = [] 
    928         for role in local_roles: 
    929             gr = grouptool.getGroupById(role[0]) 
    930             if gr: 
    931                 groups.append(gr) 
    932         if groups: 
    933             return groups[0] 
    934  
    935917    security.declarePublic('canIEdit') 
    936918    def canIEdit(self): 
    937919        mtool = getToolByName(self, 'portal_membership') 
    938920        lmtool = getToolByName(self, 'lemill_usertool') 
    939         group = self.getField('groups').get(self) 
    940         if group=='no_group' or not group: 
     921        group = self.getGroupsEditing() 
     922        if not group: 
    941923            return True # This should happen often 
    942924        member = mtool.getAuthenticatedMember() 
    943925        if not member: 
    944926            return False # This shouldn't happen at all 
     927 
    945928        membersgroups=member.getGroups() 
    946         if not membersgroups: # This happens for admins from lower acl_users, they have to try memberfolder for correct list of groups            
    947             mf= lmtool.getLeMillMemberFolder(member.id) 
    948             membersgroups=mf.getGroups() 
    949         return group in membersgroups 
     929        if not membersgroups: 
     930            return False 
     931        return group.id in [m.id for m in membersgroups] 
    950932 
    951933         
    952     security.declareProtected(MODIFY_CONTENT, 'setGroupsShared') 
    953     def setGroupsShared(self, value): 
     934    security.declareProtected(MODIFY_CONTENT, 'setGroupsEditing') 
     935    def setGroupsEditing(self, value): 
    954936        """ share a material/resource with a group(s) """ 
    955         gtool = getToolByName(self, 'portal_groups') 
    956937        reftool= getToolByName(self, 'reference_catalog') 
    957938        create_new = self.REQUEST.get('new_group_name', '') 
     
    961942            from Products.CMFPlone.utils import normalizeString 
    962943            new_group_id = normalizeString(create_new, context=self) 
    963             try: 
    964                 gtool.addGroup(new_group_id, (), ()) 
    965             except KeyError: 
    966                 # duplicate it 
    967                 return 
    968             blog = gtool.getGroupareaFolder(new_group_id) 
     944            blog_id=self.community.invokeFactory('GroupBlog',new_group_id) 
     945            blog=getattr(self.community, blog_id, None) 
    969946            blog.join_group() 
    970             blog.setProperties(id=new_group_id, title=create_new, description="") 
    971             value = new_group_id 
     947            blog.edit(title=create_new, description="") 
     948            value = blog.UID() 
    972949            discussion=self.getDiscussion(do_create=False) 
    973950            if discussion: 
     
    976953        if value == '__new_group': 
    977954            return 
    978         f = self.getField('groups') 
     955        f = self.getField('groupsEditing') 
    979956        old_value = f.get(self) 
    980957        destination=None 
    981         if old_value: 
    982             if old_value!='no_group': 
    983                 self.manage_delLocalRoles((old_value,)) 
    984958        if value: 
    985             if value!='no_group': 
    986                 self.manage_setLocalRoles(value, ('CoAuthor',)) 
    987                 destination = gtool.getGroupareaFolder(value) 
    988             else: 
    989                 # make sure that all CoAuthors are deleted 
    990                 roles=dict(self.get_local_roles()) 
    991                 for (key,dvalue) in roles.items(): 
    992                     if not 'Owner' in dvalue: self.manage_delLocalRoles((key,)) 
    993                 destination=self.community.unassigned_discussions 
    994  
     959            destination = self.getObjectByUID(value) 
     960        else: 
     961            destination=self.community.unassigned_discussions 
     962 
     963        if value!=old_value: 
    995964            f.set(self, value) 
    996965            discussion=self.getDiscussion(do_create=False) 
     
    1030999            return None             
    10311000        # If no discussion found and we do_create, then we create one 
    1032         gtool = getToolByName(self, 'portal_groups') 
    10331001        group=self.getGroupsEditing() 
    1034         if group: 
    1035             group = getattr(self.community, str(group), None) 
    1036         else: 
     1002        if not group: 
    10371003            group=self.community.unassigned_discussions 
    10381004 
     
    11651131        new.storeInHistory({}, summary='Translation of %s created' % base_obj.title_or_id()) 
    11661132                 
    1167         # give points for original author 
    1168         authid=base_obj.getAuthorsNames() 
    1169         memberfolder=mtool.getHomeFolder(authid[0]) 
    1170         if memberfolder!=None: 
    1171             memberfolder.note_action(base_obj.UID(), base_obj.portal_type, 'new translation')         
    11721133        return new         
    11731134 
  • trunk/SharedMetadata.py

    r1833 r1919  
    355355            description_msgid="help_resource_group", 
    356356            i18n_domain="lemill", 
     357            visible={'edit': 'invisible', 'view': 'invisible'}, 
     358            ), 
     359        ), 
     360    ReferenceField('groupEditing', 
     361        relationship = "is_edited_by", 
     362        schemata = 'metadata', 
     363        index="FieldIndex:schema", 
     364        vocabulary = 'getUserGroups', 
     365        enforceVocabulary = False, 
     366        multiValued = False, 
     367        widget=GroupWidget( 
     368            label="Assigned group", 
     369            label_msgid="label_assigned_group", 
     370            description="Assign one of your groups to work with this resource.", 
     371            description_msgid="help_resource_group", 
     372            i18n_domain="lemill", 
    357373            visible={'edit': 'visible', 'view': 'invisible'}, 
    358374            ), 
    359375        ), 
     376 
     377 
    360378    )) 
    361379 
  • trunk/skins/lemill/group_create_edit_script.cpy

    r1687 r1919  
    1616userName = context.portal_membership.getAuthenticatedMember().getUserName() 
    1717 
     18if addname or groupname and not addmaterial: 
     19    title=REQUEST.get('title', '') 
     20    tags=REQUEST.get('tags', '') 
     21    description=REQUEST.get('description','') 
     22 
    1823if addname: 
    19     title=REQUEST.get('title') 
    2024    addname=normalizeString(title, context=context) 
    21     context.portal_groups.addGroup(addname,(),()) 
    22     group=context.portal_groups.getGroupById(addname) 
    23     gtool = getToolByName(context, 'portal_groups') 
    24     blog = gtool.getGroupareaFolder(addname) 
    25     blog.setProperties(id=addname, title=title) 
    26  
     25    addname=context.community.invokeFactory('GroupBlog',addname) 
     26    group=context.getGroupById(addname) 
     27    group.join_group() 
     28    group.edit(tags=tags, title=title, description=description) 
    2729    msg = _(u"Group has been added.") 
    28     groupname=addname 
    29 else: 
    30     group=context.portal_groups.getGroupById(groupname) 
     30elif groupname and not addmaterial: 
     31    group=context.getGroupById(groupname) 
     32    group.edit(tags=tags, title=title, description=description) 
    3133    msg = PMF(u'Changes saved.') 
    3234 
    3335if addmaterial: 
    34     context.setGroupsShared(groupname) 
    35 if not (addmaterial and not addname): 
    36     processed={} 
    37     for id, property in context.portal_groupdata.propertyItems(): 
    38         processed[id]=REQUEST.get(id, None) 
    39  
    40  
    41     if group: 
    42         # for what reason ever, the very first group created does not exist 
    43         if not userName in group.getGroupMemberIds(): 
    44             try: 
    45                 context.acl_users.source_groups.addPrincipalToGroup(userName, groupname) 
    46                 msg = _(u"You are now member in this group.") 
    47             except: 
    48                 #probably this is just admin trying to put himself into a group, but couldn't be found from plone's acl_users. 
    49                 msg = u"Couldn't add you to group. Probably this is because you're admin and your user account is defined in Zope's root acl_users. This user folder doesn't support groups. Admins can make themselves groupable by making a copy of themselves to LeMill instance's acl_users." 
    50  
    51         processed['tags']=REQUEST.get('tags',None) 
    52         blog=context.portal_groups.getGroupareaFolder(groupname) 
    53         blog.setProperties(processed) 
    54     if addname: 
    55         blog.setMeAsOwner() 
    56  
    57     # also make these modifications to group blog 
    58     # (not implemented yet) 
     36    group.join_group() 
     37    return REQUEST.RESPONSE.redirect(context.absolute_url()) 
    5938 
    6039context.plone_utils.addPortalMessage(msg) 
    6140 
    62 if addmaterial: 
    63     return REQUEST.RESPONSE.redirect(context.absolute_url()) 
    64 else: 
    65     return REQUEST.RESPONSE.redirect(context.community.absolute_url()) 
     41return REQUEST.RESPONSE.redirect(context.community.absolute_url()) 
  • trunk/skins/lemill/join_a_group.cpt

    r1891 r1919  
    1111        <metal:fill fill-slot="main"> 
    1212        <metal:main define-macro="main"> 
    13         <tal:isFolder tal:condition="python:not mtool.getHomeFolder()" i18n:translate="text_no_home_folder"> 
    14         You don't seem to have a home folder. Please <span i18n:name="login"><a i18n:translate="text_login" href="" tal:attributes="href string:$portal_url/login_form">log in</a></span> if you haven't done so. 
    15         </tal:isFolder> 
    16         <tal:isFolder tal:condition="python:mtool.getHomeFolder()"> 
    1713 
    18         <h1 i18n:translate="heading_join_a_group_to_edit" tal:condition="context/getGroupsEditing">Join a group</h1> 
    19         <h1 i18n:translate="heading_assign_group_to_edit_or_create_new_group" tal:condition="not: context/getGroupsEditing"> 
    20             Assign group to edit or create new group 
    21         </h1> 
     14        <h1 i18n:translate="heading_join_a_group_to_edit">Join a group</h1> 
    2215 
    2316        <metal:block define-macro="join_a_group" tal:define="group_editing context/getGroupsEditing"> 
     
    6861        </form> 
    6962    </div> 
    70         <div id="join_a_group" 
    71             tal:condition="not: group_editing"> 
    72             <p> 
    73             <span tal:condition="python: wf_state == 'draft'" i18n:translate="text_draft_status"> 
    74                 This learning resource is in draft status. 
    75             </span> 
    76             <span i18n:translate="description_material_is_not_yet_edited_by_any_group"> 
    77                 Learning resources are edited by groups, but this resource is not assigned to any group yet. 
    78                 You can either choose an existing group or create a new one to edit this resource. 
    79             </span> 
    80             </p> 
    81  
    82             <form action="" name="select_group" method="post" class="enableUnloadProtection" tal:attributes="action string:${here_url}/join_a_group"> 
    83                     <tal:group repeat="group python:context.lemill_usertool.getGroupsList(user.getId())"> 
    84                         <input type="radio" name="group_name" value="" tal:attributes="value group"/><label tal:content="python:here.getTitleOfACLGroup(group)"/><br/> 
    85                     </tal:group> 
    86         <input type="radio" name="group_name" value="__new_group"/><tal:block i18n:translate="label_or_create_new_group">... or create a new group:</tal:block> 
    87         <input name="new_group_name"/> 
    88                 <div class="formControls"> 
    89                     <div id="save_button" style="display:inline"> 
    90                         <input class="context" 
    91                         tabindex="" 
    92                         type="submit" 
    93                         value="Assign group" 
    94                         id="save" 
    95                         name="form.button.SelectGroup" 
    96                         i18n:attributes="value label_assign_group;" 
    97                         tal:attributes="tabindex tabindex/next;" /> 
    98                     </div> 
    99                     <div id="cancel_button" style="display:inline"> 
    100                         <input class="context" 
    101                         tabindex="" 
    102                         type="submit" 
    103                         value="Cancel" 
    104                         id="cancel" 
    105                         name="form.button.Cancel" i18n:domain="plone"  
    106                         i18n:attributes="value label_cancel;" 
    107                         tal:attributes="tabindex tabindex/next;"/> 
    108                     </div> 
    109                 </div> 
    110                 <input type="hidden" name="addmaterial" value="1" /> 
    111                 <input type="hidden" name="form.submitted" value="1" /> 
    112             </form> 
    113  
    114             </div> 
    11563        </metal:block> 
    116         </tal:isFolder> 
    11764        </metal:main> 
    11865        </metal:fill> 
  • trunk/skins/lemill/lemill_community_view.pt

    r1859 r1919  
    77<div metal:fill-slot="main" style="width:100%" tal:define="people_results python:here.getSearchObject(portal_type='MemberFolder'); 
    88                        group_results python:here.getSearchObject(portal_type='GroupBlog');  
    9                         search_results python:people_results+group_results; 
    10                         groups python:context.lemill_usertool.getGroupsList(user.getId());"> 
     9                        search_results python:people_results+group_results;"> 
    1110     
    1211   <span tal:define="samples python:here.getSamples(search_results);" tal:condition="samples" tal:omit-tag=""> 
  • trunk/skins/lemill/portlet_add_community.pt

    r1693 r1919  
    2121<tal:block tal:condition="not:isAnon"> 
    2222 
     23<tal:defs define="homefolder mtool/getHomeFolder; 
     24    groups homefolder/getGroups; 
     25    contacts homefolder/giveSortedListOfContacts"> 
     26 
    2327<div class="tb-portlet"> 
    2428    <div class="portlet-title"> 
     
    2731    </div> 
    2832 
    29     <span tal:define="groups python:context.lemill_usertool.getGroupsList(user.getId())"> 
    30         <ul tal:condition="groups" tal:repeat="groupish groups"> 
    31              <li tal:define="groupid groupish/getGroupId; 
    32                              grouparea python:context.portal_groups.getGroupareaFolder(groupid)"> 
    33                              <a href="#"  tal:attributes="href grouparea/absolute_url"  
    34                  tal:content="grouparea/TitleOrId">  
     33        <ul tal:condition="groups" tal:repeat="group groups"> 
     34             <li> 
     35                 <a href="#"  tal:attributes="href group/getURL"  
     36                 tal:content="group/Title">  
    3537                    PLACEHOLDER 
    3638               </a>  
     
    4244        </span> 
    4345     
    44     </span> 
    4546</div> 
    4647 
     
    5051    <tal:block i18n:translate="heading_my_contacts">My contacts</tal:block> 
    5152    </div> 
    52  
    53     <span tal:define="memfolder member/getHomeFolder; 
    54                       contacts python:memfolder.giveSortedListOfContacts();"> 
    5553        <ul tal:condition="contacts" tal:repeat="contact contacts"> 
    5654            <li> 
     
    6462            Has no contacts 
    6563        </span> 
    66     </span> 
    6764</div> 
     65 
     66</tal:defs> 
    6867 
    6968</tal:block> 
  • trunk/skins/lemill/portlet_groupblog_actions.pt

    r1774 r1919  
    1111        canModerate python:here.canIModerate() or isManager; 
    1212        isPost here/isPost | nothing; 
    13         isAuthor python:isPost and member.id==here.Creator(); 
    14         isOwner python:here.amIOwner()"> 
     13        isAuthor python:isPost and member.id==here.Creator();"> 
    1514 
    1615<div class="tb-portlet" metal:define-macro="image_div"> 
     
    3938           <a href="" i18n:translate="label_undelete_topic" tal:attributes="href string:${here_url}/undelete_post">Undelete topic</a> 
    4039        </li> 
    41         <li tal:condition="python: (isOwner or canModerate)"><a i18n:translate="label_manage_members" href="" tal:attributes="href string:$blogurl/edit">Manage group</a></li> 
     40        <li tal:condition="isMember"><a i18n:translate="label_manage_members" href="" tal:attributes="href string:$blogurl/edit">Manage group</a></li> 
    4241        <li><a href="" i18n:translate="label_leave_group" tal:attributes="href string:$blogurl/leave_group">Leave group</a></li> 
    4342    </ul> 
     
    5655    </div> 
    5756 
    58     <ul tal:define="groupmembers blogobj/getGroupMembers; 
     57    <ul tal:define="groupmembers blogobj/getGroupMembersNamesAndUrls; 
    5958        n_mem python:len(groupmembers)"> 
    6059        <tal:listing condition="python: n_mem&lt;400" repeat="memberdata groupmembers"> 
    61              <li tal:define="memberroles python:memberdata[1]; 
    62                  membername python:memberdata[0]; 
    63                  member_url python:memberdata[2];"> 
     60             <li tal:define="membername python:memberdata[0]; 
     61                 member_url python:memberdata[1];"> 
    6462                 <a href="#" tal:attributes="href member_url" tal:content="membername">PLACEHOLDER</a> 
    6563             </li> 
     
    7371</div> 
    7472 
    75             <div class="tb-portlet" tal:define=" 
    76                 resources_n python:blogobj.getGroupMaterials(n=True); 
    77                 "> 
    78                 <div class="portlet-title"> 
    79                     <img src="transparent.png" alt="" class="smallicon" /> 
    80                     <tal:block i18n:translate="heading_groups_resources">Group's resources</tal:block> 
    81                 </div> 
     73<div class="tb-portlet" tal:define=" 
     74    resources_n python:blogobj.getGroupMaterials(n=True); 
     75    "> 
     76    <div class="portlet-title"> 
     77        <img src="transparent.png" alt="" class="smallicon" /> 
     78        <tal:block i18n:translate="heading_groups_resources">Group's resources</tal:block> 
     79    </div> 
    8280 
    83                 <ul> 
    84                     <li> 
    85                         <a i18n:translate="" href="portfolio" tal:attributes="href python:'portfolio?getGroupsShared=%s&amp;portal_type=resource' % blogobj.getId()">Content</a> 
    86                     (<span tal:replace="resources_n" />) 
    87                     </li> 
    88                     <li> 
    89                     <a i18n:translate="label_tag_cloud" href="portfolio" tal:attributes="href python:'portfolio?getGroupsShared=%s' % blogobj.getId()">Tag cloud</a> 
    90                     </li> 
     81    <ul> 
     82        <li> 
     83            <a i18n:translate="" href="portfolio" tal:attributes="href python:'portfolio?getRawGroupEditing=%s&amp;portal_type=resource' % blogobj.UID()">Content</a> 
     84        (<span tal:replace="resources_n" />) 
     85        </li> 
     86        <li> 
     87        <a i18n:translate="label_tag_cloud" href="portfolio" tal:attributes="href python:'portfolio?getRawGroupEditing=%s' % blogobj.UID()">Tag cloud</a> 
     88        </li> 
    9189 
    92                     
    93                 </ul> 
    94            </div> 
     90         
     91    </ul> 
     92</div> 
    9593 
    9694 
  • trunk/skins/lemill/portlet_member.pt

    r1756 r1919  
    2222            </div> 
    2323 
    24             <tal:defs define="logged_id python:mtool.getAuthenticatedMember().getId();"> 
     24            <tal:defs define="logged_id python:mtool.getAuthenticatedMember().getId(); 
     25            homefolder mtool/getHomeFolder"> 
    2526                            <div class="tb-portlet" tal:condition="python:not isAnon and context.getMemberId()!=logged_id"> 
    26                 <ul tal:define="groups python:context.lemill_usertool.getGroupsList(logged_id); 
     27                <ul tal:define="groups homefolder/getGroups; 
    2728                    show_remove here/showRemoveContactLink"> 
    2829                    <li tal:condition="groups"> 
     
    4950                </div> 
    5051 
    51                 <span tal:define="groups python:context.lemill_usertool.getGroupsList(context.getMemberId())"> 
     52                <span tal:define="groups context/getGroups"> 
    5253                    <ul tal:condition="groups" tal:repeat="groupish groups"> 
    53                          <li tal:define="groupid groupish/getGroupId; 
    54                                          grouparea python:context.portal_groups.getGroupareaFolder(groupid)"> 
    55                                          <a href="#"  tal:attributes="href grouparea/absolute_url"  
    56                              tal:content="grouparea/TitleOrId">  
     54                         <li> 
     55                            <a href="#"  tal:attributes="href groupish/getURL"  
     56                             tal:content="groupish/Title">  
    5757                                PLACEHOLDER 
    5858                           </a> 
  • trunk/skins/lemill/widget_group.pt

    r1785 r1919  
    2121    <metal:define define-macro="edit"> 
    2222 
    23         <tal:supersecurity condition="python: here.amIOwner() or here.amIManager()"> 
    2423        <metal:use use-macro="field_macro | here/widgets/field/macros/edit"> 
    2524 
     
    8079 
    8180        </metal:use> 
    82         </tal:supersecurity> 
    8381 
    8482    </metal:define> 
  • trunk/version.txt

    r1882 r1919  
    1 1.12 
     11.12.2 
Note: See TracChangeset for help on using the changeset viewer.