Changeset 2883

Show
Ignore:
Timestamp:
09/24/09 16:46:03 (2 years ago)
Author:
jukka
Message:

Fixed #1889 and Fixed #1911 . Refactored collection ordering.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/Collection.py

    r2878 r2883  
    249249 
    250250 
    251     def getLargestCount(self, reftype='relatedContent'): 
    252         field = self.Schema().get(reftype) 
    253         rtype=field.relationship 
    254         f = self.getReferenceImpl(relationship=rtype) 
    255  
    256         highest = 1001 
    257         numbs = [] 
    258         for a in f: 
    259             try: 
    260                 numbs.append(a.collection_position) 
    261             except AttributeError: 
    262                 pass 
    263         if len(numbs)>0: 
    264             highest = max(numbs)+100 
    265         else: 
    266             highest += 100 
    267         return highest 
    268  
    269251    def getReferenceType(self, object): 
    270252        """ Which reference should be used for this object? Returns string. """ 
     
    293275        value = field.getRaw(self) 
    294276        value.append(UID) 
    295         field.set(self, value, collection_position=self.getLargestCount(reftype)
     277        self._setOrderedReferences(value, reftype
    296278        self.updateStory() 
    297279        obj.recalculateScore() 
     
    306288        new=self.isThisGoodStory() 
    307289        if old != new: 
    308             self.recalculateScoresForRelatedResources()         
    309290            self.setGoodStory(new) 
    310291            self.reindexObject(['getGoodStory']) 
     292            for obj in self.getContent()+self.getMethods()+self.getTools(): 
     293                obj.recalculateScore() 
     294                obj.reindexObject(['getScore']) 
     295 
    311296 
    312297    def isThisGoodStory(self): 
     
    338323        return good_tools 
    339324 
    340     def recalculateScoresForRelatedResources(self): 
    341         # A helper method to recalculate scores or resources and reindex them if state of story changes 
    342         c = self.getContent() 
    343         for obj in c: 
    344             obj.recalculateScore() 
    345             obj.reindexObject() 
    346         m = self.getMethods() 
    347         for obj in m: 
    348             obj.recalculateScore() 
    349             obj.reindexObject() 
    350         t = self.getTools() 
    351         for obj in t: 
    352             obj.recalculateScore() 
    353             obj.reindexObject() 
    354         #Collections used score calculator method from Resources, the only score they can get is 1 
    355         #XXX This code it not needed until we get a recalculator 
    356         #cl = self.getRelatedCollections() 
    357         #for obj in cl: 
    358         #    obj.recalculateScore() 
    359         #    obj.reindexObject() 
    360  
    361325    def getItemCount(self): 
    362326        """ return how many items are in collection """ 
     
    381345 
    382346    def getSortedList(self, reftype='relatedContent'): 
    383         #f = self.getField('refsToResources') 
    384347        field = self.Schema().get(reftype) 
    385         rtype=field.relationship 
    386         f = self.getReferenceImpl(relationship=rtype) 
    387         arr = [] 
    388         err_base = 12345123 
    389         for a in f: 
    390             try: 
    391                 i = a.collection_position 
    392             except AttributeError: 
    393                 i = err_base + 100 
    394                 a.collection_position = i 
    395             arr.append([i, a]) 
    396         arr.sort() 
    397         return arr 
     348        if reftype == 'relatedMethods' or reftype=='relatedTools': 
     349            sortable = [(ref.targetId(), ref) for ref in self.getReferenceImpl(relationship=field.relationship)] 
     350        else:               
     351            sortable = [(getattr(ref,'collection_position',100), ref) for ref in self.getReferenceImpl(relationship=field.relationship)] 
     352        sortable.sort() 
     353        return [ref for i, ref in sortable] 
    398354 
    399355    def getBlurp(self): 
     
    408364    def getResources(self, reftype='relatedContent', private_materials=True, pdf_types=False): 
    409365        """ ... """ 
    410         #return self.getRefsToResources() 
    411         sorted = self.getSortedList(reftype) 
    412         lutool = getToolByName(self, 'lemill_usertool') 
    413         user = lutool.getAuthenticatedId() 
    414         arr = [] 
    415         for x in sorted: 
    416             target = x[1].getTargetObject() 
     366        user = getToolByName(self, 'lemill_usertool').getAuthenticatedId() 
     367        manager=self.amIManager()         
     368        resources = [] 
     369        for ref in self.getSortedList(reftype): 
     370            target = ref.getTargetObject() 
    417371            if pdf_types and target.meta_type not in ['MultimediaMaterial', 'ExerciseMaterial', 'LessonPlan', 'SchoolProjectMaterial', 'LeMillReference', 'Activity', 'Tool']: 
    418372                continue 
    419             # only resource owner and manager see private resources 
    420             if private_materials and (user==target.Creator() or self.amIManager()): 
    421                 if target.getState() in ['draft','public','private']: 
    422                     arr.append(x[1].getTargetObject()) 
    423             elif target.getState() in ['draft','public']: 
    424                 arr.append(x[1].getTargetObject()) 
    425  
    426         # Only Tools and Methods should get sorted by name 
    427         if reftype not in ['relatedContent', 'relatedCollections']: 
    428             mod_resources = [(x.Title(), x) for x in arr] 
    429             mod_resources.sort() 
    430             arr = [x[1] for x in mod_resources] 
    431         return arr 
     373            if target.state=='draft' or target.state=='public': 
     374                resources.append(target) 
     375            elif private_materials and target.state=='private' and (user==target.Creator() or manager): 
     376                resources.append(target) 
     377        return resources 
     378 
    432379 
    433380    def getResourcesMetadata(self, reftype='relatedContent'): 
    434381        """ ... """ 
    435         uid_catalog=getToolByName(self, 'uid_catalog') 
    436         sorted = self.getSortedList(reftype) 
    437         lutool = getToolByName(self, 'lemill_usertool') 
    438         user = lutool.getAuthenticatedId() 
    439         arr = [] 
    440         for x in sorted: 
    441             target = x[1].getTargetObject() 
    442             states = ['draft', 'public'] 
    443             # only resource owner and manager see private resources 
    444             if user==target.Creator() or self.amIManager(): 
    445                 states.append('private') 
    446             if target.getState() in states: 
    447                 arr.append(uid_catalog(UID=x[1].targetUID)[0]) 
    448         # Only Tools and Methods should get sorted by name 
    449         if reftype not in ['relatedContent', 'relatedCollections']: 
    450             mod_resources = [(x.Title, x) for x in arr] 
    451             mod_resources.sort() 
    452             arr = [x[1] for x in mod_resources] 
    453         return arr 
     382        pc=getToolByName(self, 'portal_catalog') 
     383        user = getToolByName(self, 'lemill_usertool').getAuthenticatedId() 
     384        manager=self.amIManager()         
     385        results=[] 
     386        for ref in self.getSortedList(reftype): 
     387            md=pc(UID=ref.targetUID)[0] 
     388            if md.getState=='draft' or md.getState=='public': 
     389                results.append(md) 
     390            elif md.getState=='private' and (md.Creator==user or manager): 
     391                results.append(md) 
     392        return results 
    454393 
    455394    def isResourceInCollection(self, resource): 
     
    491430 
    492431 
     432    def _setOrderedReferences(self, ordered_list, reftype='relatedContent'): 
     433        """ setter that stores the index of each element in list with reference object. ordered_list = list of uids """ 
     434        field = self.getField(reftype) 
     435        field.set(self, ordered_list) 
     436        refs = self.getReferenceImpl(relationship=field.relationship) 
     437        for ref in refs: 
     438            i = ordered_list.index(ref.targetUID) 
     439            ref.collection_position=i 
     440             
     441 
    493442    security.declareProtected(MODIFY_CONTENT,'moveUpContent') 
    494443    def moveUpContent(self, objid,REQUEST=None): 
     
    510459        field = self.getField(reftype) 
    511460        sorted = self.getSortedList(reftype) 
    512         previous_pos = 0 
    513         cur_pos = 0 
    514         count = 0 
    515         for x in sorted: 
    516             if x[1].getTargetObject().id == objid: 
    517                 cur_pos = count 
     461        found=0 
     462        for i, ref in enumerate(sorted): 
     463            if ref.targetId() == objid: 
     464                found = i 
    518465                break 
    519             elif x[1].getTargetObject().getState != 'deleted': 
    520                 previous_pos = count 
    521             count += 1 
    522         if cur_pos > 0: 
    523             prev_uid = sorted[previous_pos][1].getTargetObject().UID() 
    524             prev_pos = sorted[previous_pos][1].collection_position 
    525             curr_uid = sorted[cur_pos][1].getTargetObject().UID() 
    526             curr_pos = sorted[cur_pos][1].collection_position 
    527              
    528             sorted.remove(sorted[cur_pos]) 
    529             sorted.remove(sorted[previous_pos]) 
    530             new_list = [] 
    531             [ new_list.append(x[1].getTargetObject()) for x in sorted ] 
    532              
    533             field.set(self, new_list) 
    534             new_list.append(curr_uid) 
    535             field.set(self, new_list, collection_position=prev_pos) 
    536             new_list.append(prev_uid) 
    537             field.set(self, new_list, collection_position=curr_pos) 
    538             #new_list = [] 
    539             #for x in sorted: 
    540             #    new_list.append(x[1].getTargetObject()) 
    541             #field.set(self, new_list) 
     466        if found: 
     467            swap=sorted[found-1] 
     468            sorted[found-1]=sorted[found] 
     469            sorted[found]=swap 
     470            new_list=[ref.targetUID for ref in sorted] 
     471            self._setOrderedReferences(new_list, reftype) 
    542472 
    543473 
     
    560490        """ move down """ 
    561491        field = self.getField(reftype) 
    562         sorted = self.getSortedList(reftype=reftype) 
    563         cur_pos = 0 
    564         cur_pos_get = False 
    565         next_position = 0 
    566         count = 0 
    567         for x in sorted: 
    568             if x[1].getTargetObject().id == objid: 
    569                 cur_pos = count 
    570                 cur_pos_get = True 
    571             elif cur_pos_get and x[1].getTargetObject().getState() != 'deleted': 
    572                 next_position = count 
     492        sorted = self.getSortedList(reftype) 
     493        found=10000 
     494        for i, ref in enumerate(sorted): 
     495            if ref.targetId() == objid: 
     496                found = i 
    573497                break 
    574             count += 1 
    575         if next_position < len(sorted): 
    576             next_uid = sorted[next_position][1].getTargetObject().UID() 
    577             next_pos = sorted[next_position][1].collection_position 
    578             curr_uid = sorted[cur_pos][1].getTargetObject().UID() 
    579             curr_pos = sorted[cur_pos][1].collection_position 
    580  
    581             sorted.remove(sorted[next_position]) 
    582             sorted.remove(sorted[cur_pos]) 
    583             new_list = [] 
    584             [ new_list.append(x[1].getTargetObject()) for x in sorted ] 
    585              
    586             field.set(self, new_list) 
    587             new_list.append(curr_uid) 
    588             field.set(self, new_list, collection_position=next_pos) 
    589             new_list.append(next_uid) 
    590             field.set(self, new_list, collection_position=curr_pos) 
     498        if len(sorted)>found+1: 
     499            swap=sorted[found+1] 
     500            sorted[found+1]=sorted[found] 
     501            sorted[found]=swap 
     502            new_list=[ref.targetUID for ref in sorted] 
     503            self._setOrderedReferences(new_list, reftype) 
    591504 
    592505    def getLearningStoryText(self): 
  • trunk/Discussable.py

    r2879 r2883  
    6262    def getDiscussionURL(self): 
    6363        """ Returns url for page that displays comments """ 
    64         return '%s/discussion' % self.absolute_url(
     64        return '/'.join((self.absolute_url(), 'discussion')
    6565 
    6666    def getCommentURL(self, comment_id): 
    6767        """ Returns url for a certain comment id, validates if it looks proper """ 
    6868        if comment_id.isdigit(): 
    69             return '#'.join(self.getDiscussionURL(), comment_id
     69            return '#'.join((self.getDiscussionURL(), comment_id)
    7070        else: 
    7171            return self.getDiscussionURL() 
  • trunk/LargeSectionFolder.py

    r2882 r2883  
    942942 
    943943 
    944  
    945  
    946944##################### Subclasses        ################################ 
    947945 
  • trunk/LeMillUserTool.py

    r2868 r2883  
    117117            return md.getNicename 
    118118        if i18name: 
    119             i18name=' i18n:name="%s" ' % i18name 
     119            i18name=' i18n:name="'+i18name+'" ' 
    120120        if open_in_new_window: 
    121             return """<a target="_blank" href="%s"%s>%s</a>""" % (md.getURL(), i18name, md.getNicename
    122         else: 
    123             return """<a href="%s"%s>%s</a>""" % (md.getURL(), i18name, md.getNicename
     121            return "".join(('<a target="_blank" href="',md.getURL(), '"',i18name,'>',md.getNicename,'</a>')
     122        else: 
     123            return "".join(('<a href="',md.getURL(), '"',i18name,'>',md.getNicename,'</a>')
    124124         
    125125 
  • trunk/skins/lemill/collection_view.cpt

    r2878 r2883  
    99          tal:attributes="href string:${here_url}/RSS"/> 
    1010      </metal:headslot> 
    11  
    12  
    1311    </head> 
    1412 
    1513  <body> 
    1614    <metal:fill fill-slot="main"> 
    17       <metal:main_macro define-macro="body" 
    18             tal:define="portal_type python:here.getPortalTypeName().lower().replace(' ', '_'); 
    19             base_macros here/base/macros; 
    20             view_template python:'%s_view' % portal_type; 
    21             view_macros python:path('here/%s/macros|nothing' % view_template); 
    22             body_macro view_macros/body | body_macro | base_macros/body; 
    23             folderlisting_macro view_macros/folderlisting | folderlisting | base_macros/folderlisting; 
    24             footer_macro view_macros/footer | footer_macro | base_macros/footer; 
    25             errors python:request.get('errors', {}); 
    26             use_view_action site_properties/typesUseViewActionInListings; 
    27             searchterm string:; 
    28             isOwner here/amIOwner; 
    29             collection_creator here/Creator; 
    30             "> 
     15      <metal:header define-macro="header"> 
     16        <h1 i18n:translate="collection_title">Collection: <span i18n:name="title" tal:replace="here/Title"/></h1> 
     17        <span i18n:translate="creator">creator</span>: <a tal:replace="structure python:lutool.linkTo(here.Creator())"/> 
     18      </metal:header> 
    3119 
    32         <h1 i18n:translate="collection_title">Collection: <span i18n:name="title" tal:replace="here/Title"/></h1> 
    33         <span i18n:translate="creator">creator</span>: <a tal:replace="structure python:lutool.linkTo(collection_creator)"/> 
     20      <metal:main_macro define-macro="body" tal:define="collection_creator here/Creator"> 
    3421 
    35     <tal:content tal:define="resources python:here.getResources(reftype='relatedContent');" condition="resources"> 
     22       <tal:content tal:define="resources python:here.getResources(reftype='relatedContent');" condition="resources"> 
    3623        <h2 i18n:translate="label_content">Content</h2> 
    3724        <table width="100%" border="0" cellpadding="4" cellspacing="0"> 
     
    4330            </tr> 
    4431        </table> 
    45     </tal:content> 
     32       </tal:content> 
    4633     
    4734    <tal:methods tal:define="resources python:here.getResources(reftype='relatedMethods');" condition="resources"> 
     
    8168 
    8269 
    83         <h2 tal:condition="python: here.Description() or isOwner" i18n:translate="label_teaching_and_learning_story">Teaching and learning story</h2>  
     70        <h2 tal:condition="python: here.Description() or here.amIOwner()" i18n:translate="label_teaching_and_learning_story">Teaching and learning story</h2>  
    8471        <div tal:condition="here/Description" tal:replace="structure here/getLearningStoryText" /> 
    85         <p tal:condition="python: isOwner and not here.Description()" i18n:translate="learning_story_explanation">You have not written a story about this collection yet. 
     72        <p tal:condition="python: here.amIOwner() and not here.Description()" i18n:translate="learning_story_explanation">You have not written a story about this collection yet. 
    8673If you have used these resources in a learning session you can share 
    87 your experiences by <span i18n:name="newstory"><a href="edit" i18n:translate="link_writing_teaching_and_learning_story">writing a teaching and learning story</a></span>.</p> 
     74your experiences by <span i18n:name="newstory"><a href="edit" tal:attributes="href string:${here_url}/edit"  i18n:translate="link_writing_teaching_and_learning_story">writing a teaching and learning story</a></span>.</p> 
    8875 
    8976        <div class="visualClear" style="height:20px"><!-- --></div> 
  • trunk/skins/lemill/createObject.cpy

    r2874 r2883  
    6060    state.setId(script_id) 
    6161 
    62 if message: 
    63      
    6462return state.set(context=o)