Changeset 2378


Ignore:
Timestamp:
05/12/08 16:46:59 (12 years ago)
Author:
jukka
Message:

Fixed #1734.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/ExerciseMaterial.py

    r2351 r2378  
    8686        dump= '\n'.join([x[0] for x in values if x[1] not in ['media_piece', 'multiple_choices']]) 
    8787        return dump 
     88 
     89    def getOnlyRawText(self): 
     90        field=self.getField('bodyText') 
     91        values = field.getRaw(self) 
     92        dump= '\n'.join([x[0] for x in values if x[1] not in ['media_piece', 'multiple_choices']]) 
     93        return dump 
     94 
    8895 
    8996    def isCorrectAnswer(self, chapter, answer_index): 
  • trunk/LargeSectionFolder.py

    r2375 r2378  
    2929import re, datetime, urllib 
    3030from AccessControl import ClassSecurityInfo 
    31 from permissions import MODIFY_CONTENT, ADD_CONTENT_PERMISSION 
     31from permissions import MODIFY_CONTENT, ADD_CONTENT_PERMISSION, ModerateContent 
    3232from Products.LeMill import LeMillMessageFactory as _ 
    3333import time 
     
    808808    ################################# 
    809809 
    810     security.declareProtected(MANAGE_PORTAL, 'convertResource') 
     810    security.declareProtected(ModerateContent, 'convertResource') 
    811811    def convertResource(self, REQUEST): 
    812812        """ Copy values of some fields to new object and redirect old references """ 
     
    823823                trial_run=False 
    824824 
    825         from_obj=getattr(self, from_obj_id) 
     825        from_obj=getattr(self, from_obj_id,None) 
    826826        if not from_obj: 
    827827            raise "base object for resource conversion doesn't exist" 
     
    884884                        val=new_val 
    885885                    else: 
    886                         val=from_obj.getOnlyText() 
    887                 if from_obj_type == 'MultimediaMaterial': 
     886                        val=from_obj.getOnlyRawText() 
     887                elif from_obj_type == 'MultimediaMaterial': 
    888888                    if to_obj_type == 'ExerciseMaterial': 
    889889                        if val[0][0]=='text_block': 
    890890                            val[0][0]='guidelines' 
    891891                    else: 
    892                         val=from_obj.getOnlyText() 
     892                        val=from_obj.getOnlyRawText() 
    893893            copied_val = None 
    894894            try: 
     
    920920        # LeMillReferences use descriptions instead of bodytexts while they still have bodytexts: 
    921921        if to_obj_type=='LeMillReference': 
     922            k='bodyText' 
    922923            from_accessor=from_schema['bodyText'].getEditAccessor(from_obj) 
    923924            to_mutator = to_schema['description'].getMutator(to_obj) 
    924925            copyvalue(from_accessor, to_mutator, k) 
    925926        if from_obj_type=='LeMillReference': 
     927            k='description' 
    926928            from_accessor=from_schema['description'].getEditAccessor(from_obj) 
    927929            to_mutator = to_schema['bodyText'].getMutator(to_obj) 
  • trunk/MultimediaMaterial.py

    r2351 r2378  
    8787        return dump 
    8888 
     89    def getOnlyRawText(self): 
     90        field=self.getField('bodyText') 
     91        values = field.getRaw(self) 
     92        if values: 
     93            return '\n'.join([x[0] for x in values if x[1]=='text_block']) 
     94        return '' 
     95 
    8996    security.declareProtected(MODIFY_CONTENT,'delChapter') 
    9097    def delChapter(self, REQUEST): 
  • trunk/PresentationMaterial.py

    r2351 r2378  
    134134            return dump 
    135135 
     136    def getOnlyRawText(self): 
     137        field=self.getField('bodyText') 
     138        values = field.getRaw(self) 
     139        if values: 
     140            return '\n'.join([x[0] for x in values if x[1]=='caption']) 
     141        return '' 
     142 
    136143 
    137144    def slideCount(self): 
     
    140147 
    141148 
    142     def getSlide(self, slidenr, count_captions=False): 
    143         """ fetch the referenced piece. if count_captions=True, then suppose that slidenr is actual chapterindex,  
    144         otherwise assume that  captions are not included in slidenr """ 
    145         if not count_captions: 
    146             slidenr=slidenr*2 
     149    def getExternalFilePath(self, instance, chapter_text, edit_size=True): 
     150        print chapter_text 
     151        if edit_size: 
     152            prefix='edit_' 
     153        else: 
     154            prefix='' 
     155        return  
     156 
     157 
     158    def getSlidesAsTuples(self): 
     159        """ Helper method for slideshows, returns (slide_src, thumb_src , caption) -tuples """ 
     160        thelist=[] 
     161        caption=slide_src=thumb_src='' 
     162        for (chapter,chapter_type) in self.getRawBodyText(): 
     163            if chapter_type=='caption': 
     164                thelist.append((slide_src, thumb_src, chapter)) 
     165            elif chapter_type=='image_piece': 
     166                if chapter.startswith('EFS:'): 
     167                    slide_src='%s/%s_files/%s' % (readDir, self.UID(), chapter.split(':',1)[1]) 
     168                    thumb_src='%s/%s_files/small_%s' % (readDir, self.UID(), chapter.split(':',1)[1]) 
     169                elif self.isUid(chapter): 
     170                    piece=self.getObjectByUID(chapter) 
     171                    if piece and hasattr(piece, 'image_large') and hasattr(piece, 'image_small'): 
     172                        slide_src='%s/image_large' % piece.absolute_url() 
     173                        thumb_src='%s/image_small' % piece.absolute_url() 
     174                    else: 
     175                        slide_src='' 
     176                        thumb_src=''                         
     177            else: 
     178                slide_src='' 
     179                thumb_src='' 
     180        return thelist  
     181 
     182 
     183    def getSlideThumbnailURL(self, slidenr): 
     184        """ fetch the thumbnail url for referenced piece or external image. Assumes that captions are not counted in slidenr:s """ 
     185        slidenr=slidenr*2 
    147186        chpsfield=self.getField('bodyText') 
    148187        chps=chpsfield.get(self) 
    149188        if slidenr<len(chps): 
    150             if chps[slidenr][0] in ('', 'thisisamediapiecethisisamediapie'): 
    151                 return 0 
    152             piece=chpsfield.getObjectByUID(self, chps[slidenr][0]) 
    153             return piece 
    154         else: 
    155             return 0 
    156  
     189            slideid=chps[slidenr][0] 
     190            if not slideid: # Empty 
     191                return None 
     192            elif slideid.startswith("EFS:"): # External 
     193                return self.getExternalImageURL('small_%s' % slideid[4:])              
     194            else: # Piece 
     195                piece=chpsfield.getObjectByUID(self, slideid) 
     196                if piece: 
     197                    return piece.image_small.absolute_url() 
     198        return None 
     199 
     200    def getSlide(self, chapter): 
     201        """ Create tuple of (img_url, title, piece_url) of piece or external image. Assume that chapter is UID or 'EFS:' """         
     202        if chapter.startswith("EFS:"): 
     203            img_url=self.getExternalImageURL(chapter) 
     204            title='%s-%s' % (self.Title(), chapter[4:]) 
     205            piece_url='make_piece?EFS=%s' % chapter[4:] 
     206            return (img_url, title, piece_url) 
     207        elif chapter: 
     208            piece=self.getObjectByUID(self, chapter) 
     209            return (piece.image_large.absolute_url(), piece.Title(), piece.absolute_url()) 
     210        else: 
     211            return None             
     212 
     213 
     214    def getExternalImageURL(self, filename): 
     215        """ Build url for image stored in  external file """ 
     216        if filename.startswith("EFS:"): 
     217            filename=filename[4:] 
     218        return '%s/%s_files/%s' % (readDir, self.UID(), filename) 
    157219 
    158220    def convertPiecesToExternalImages(self): 
    159221        """ If this presentation is only that uses its' pieces, convert them to external slides """ 
    160         dir_presentation='%s_slides' % self.UID() 
     222        dir_presentation='%s_files' % self.UID() 
    161223        target_dir='%s/%s' % (writeDir, dir_presentation)         
    162224        if not os.path.exists(target_dir): 
    163225            os.makedirs(target_dir) 
    164         else: 
    165             print 'This should run only once: %s (%s) already has _slides-folder.' % (self.id, self.UID()) 
    166             return False 
     226        #else: 
     227        #    print 'This should run only once: %s (%s) already has _slides-folder.' % (self.id, self.UID()) 
     228        #    return False 
    167229        os.chdir(target_dir) 
    168230        free_n=1 
    169  
    170         def replacePiece(piece,free_n): 
    171             file=piece.getFile() 
    172             val = file.data 
    173             s = cStringIO.StringIO(val) 
    174             s.seek(0) 
    175             image = PIL.Image.open(s) 
    176             filename='slide_%s.png' % free_n 
    177             while os.path.lexists(filename): 
    178                 free_n=free_n+1 
    179                 filename='slide_%s.png' % free_n 
    180             original_mode = image.mode 
    181             if original_mode == '1': 
    182                 image = image.convert('L') 
    183             elif original_mode == 'P': 
    184                 image = image.convert('RGBA') 
    185             image.thumbnail((700,525), PIL.Image.ANTIALIAS) 
    186             image.save(filename) 
    187             image.thumbnail((500,500), PIL.Image.ANTIALIAS) 
    188             image.save('edit_slide_%s.png' % free_n) 
    189              
    190             return ('EFS:%s' % filename, free_n+1) 
    191  
     231        dir_empty=True 
    192232        field=self.getField('bodyText')         
    193233        bodyText=field.getRaw(self) 
    194234        new_bodyText=[] 
     235        print 'Cleaning presentation %s' % self.id 
    195236        for (chapter, chapter_type) in bodyText: 
    196             if chapter_type=='image_piece': 
    197                 print chapter 
    198                 piece=self.getObjectByUID(chapter) 
    199                 print piece 
    200                 if piece and len(piece.getResourcesUsingPiece())==1: 
    201                     (chapter, free_n)=replacePiece(piece, free_n) 
     237            if chapter_type=='image_piece' and chapter: 
     238                if chapter.startswith('EFS:'): 
     239                    print 'External image already:%s ' % chapter 
     240                    dir_empty=False 
     241                else: 
     242                    piece=self.getObjectByUID(chapter) 
     243                    used_in=len(piece.getResourcesUsingPiece(return_objects=True)) 
     244                    if piece: 
     245                        if used_in<2: 
     246                            file=piece.getFile() 
     247                            #try: 
     248                            print 'Converting %s' % piece.id 
     249                            (chapter, free_n)=self.createExternalImages(file, free_n) 
     250                            #except: 
     251                            #    print 'PROBLEM with %s' % piece.id 
     252                            #    new_bodyText.append((chapter,chapter_type)) 
     253                            #    continue 
     254                            dir_empty=False 
     255                            print 'OK %s' % piece.id 
     256                            try: 
     257                                self.aq_parent._delObject(piece.id) 
     258                            except KeyError: 
     259                                try: 
     260                                    self.trash._delObject(piece.id) 
     261                                except KeyError: 
     262                                    pass 
     263                        else: 
     264                            print 'piece %s used in multiple places (%s)' % (piece.id, used_in) 
     265 
    202266            new_bodyText.append((chapter,chapter_type)) 
    203         print new_bodyText 
    204         field.set(self, new_bodyText) 
    205         self.reindexObject() 
    206  
    207  
    208     def uploadSlidesToDir(self): 
    209         """ take all files from request and save them to UID_files/slide_1...slide_n.png """ 
    210         request=self.REQUEST 
     267        if dir_empty: 
     268            os.chdir(writeDir) 
     269            os.rmdir(dir_presentation) 
     270        if new_bodyText!=bodyText: 
     271            field.set(self, new_bodyText) 
     272            self.reindexObject() 
     273 
     274 
     275    security.declarePrivate('createExternalImages')  
     276    def createExternalImages(self, file, free_n): 
     277        print type(file) 
     278        if hasattr(file, 'data'): 
     279            while hasattr(file, 'data'): 
     280                file = file.data 
     281                #print type(file), 
     282                #print '.', 
     283            print 'DATA' 
     284            s = cStringIO.StringIO(file) 
     285            s.seek(0) 
     286            image = PIL.Image.open(s) 
     287        else: 
     288            print 'SOMETHING READABLE' 
     289            s = cStringIO.StringIO(file.read()) 
     290            s.seek(0) 
     291            image = PIL.Image.open(s) 
     292        filename='slide_%s.png' % free_n 
     293        while os.path.lexists(filename): 
     294            free_n=free_n+1 
     295            filename='slide_%s.png' % free_n 
     296        original_mode = image.mode 
     297        if original_mode!='RGB': 
     298            image = image.convert('RGB') 
     299        #if original_mode == '1': 
     300        #    image = image.convert('L') 
     301        #elif original_mode == 'P': 
     302        #    image = image.convert('RGBA') 
     303        image.thumbnail((700,525), PIL.Image.ANTIALIAS) 
     304        #image.thumbnail((700,525)) 
     305        image.save(filename) 
     306        image.thumbnail((500,500), PIL.Image.ANTIALIAS) 
     307        image.save('edit_%s' % filename) 
     308        image.thumbnail((120,120), PIL.Image.ANTIALIAS) 
     309        image.save('small_%s' % filename)         
     310        return ('EFS:%s' % filename, free_n+1) 
     311 
     312 
     313 
     314 
     315    security.declarePrivate('createPieceFromSlide') 
     316    def createPieceFromSlide(self, chapter): 
     317        lemill_tool=getToolByName(self, 'lemill_tool') 
     318        if type(chapter)==tuple: 
     319            chapter=chapter[0] 
     320        if chapter.startswith('EFS:'): 
     321            chapter=chapter[4:] 
     322        dir_presentation='%s_files' % self.UID() 
     323        target_dir='%s/%s' % (writeDir, dir_presentation)         
     324        if not os.path.exists(target_dir): 
     325            return False 
     326        os.chdir(target_dir)             
     327        id='-'.join((self.id,filename)) 
     328        filename='-'.join((self.Title(),filename)) 
     329        new_id = self.invokeFactory('Piece', id, title=filename) 
     330        new_piece = getattr(self, new_id) 
     331        file=open(chapter) 
     332        new_piece.setFile(file.read())                         
     333        file.close() 
     334        return new_piece 
     335 
     336 
     337 
     338 
     339    security.declareProtected(MODIFY_CONTENT,'createExternalImagesFromForm') 
     340    def createExternalImagesFromForm(self): 
     341        """ get uploads from form, order them to look like they're coming from SlideWidget and send them to set-method of ChapterField """ 
     342        REQUEST=self.REQUEST 
    211343        dir_presentation='%s_files' % self.UID() 
    212344        target_dir='%s/%s' % (writeDir, dir_presentation)         
     
    214346            os.makedirs(target_dir) 
    215347        os.chdir(target_dir) 
    216         free_n=1 
    217          
    218         chapters= self.getField('bodyText').get(self) 
    219         n_pieces= int(REQUEST.get('n_pieces',10)) 
    220  
    221  
    222  
    223     security.declarePrivate('createPieceFromSlide') 
    224     def createPieceFromSlide(self, chapter): 
    225         if type(chapter)==tuple: 
    226             chapter=chapter[0] 
    227         if chapter.startswith('EFS:'): 
    228             chapter=chapter[4:] 
    229         dir_presentation='%s_slides' % self.UID() 
    230         target_dir='%s/%s' % (writeDir, dir_presentation)         
    231         if not os.path.exists(target_dir): 
    232             return False 
    233         os.chdir(target_dir)             
    234         image = PIL.Image.open(chapter) 
    235  
    236  
    237  
    238     security.declarePrivate('createSlideFromFile') 
    239     def createSlideFromFile(self, slide_nr, file): 
    240  
    241         original_file=StringIO(file) 
    242         image = PIL.Image.open(original_file) 
    243         image.save('slide_%s.png' % slide_nr) 
    244 # 
    245 #        target_dir='%s/%s' % (EXTERNAL_CONTENT_STORAGE, dir_presentation)         
    246 #        if not os.path.exists(target_dir): 
    247 #            os.makedirs(target_dir) 
    248 #        os.chdir(target_dir) 
    249 # 
    250 #        external_dir=config. 
    251 #            birthplace=self.content 
    252 #        if file.headers['Content-Type'] not in MIMETYPE_WHITELIST: 
    253 #            return None 
    254 #        id = birthplace.generateUniqueId('Piece') 
    255 #        filename=file.filename.split('/')[-1] # Windows brings in the whole path as filename, take only last part 
    256 #        filename=filename.split('\\')[-1] # stupid windows                     
    257 #        if not self.checkTitle(title=filename): # try with filename 
    258 #            if parent_object: 
    259 #                filename='-'.join((parent_object.Title(),filename)) # else use longer version 
    260 #            else: 
    261 #                filename=id 
    262 #        new_id = birthplace.invokeFactory('Piece', id, title=filename) 
    263 #        new_piece = getattr(birthplace, new_id) 
    264 #        new_piece.setFile(file)                         
    265 #        return new_piece 
    266 # 
    267 #    security.declareProtected(permissions.ModifyPortalContent, 'rescaleOriginal') 
    268 #    def rescaleOriginal(self, value, **kwargs): 
    269 #        """rescales the original image and sets the data 
    270 # 
    271 #        for self.original_size or self.max_size 
    272 #         
    273 #        value must be an OFS.Image.Image instance 
    274 #        """ 
    275 #        data = str(value.data) 
    276 #        if not HAS_PIL: 
    277 #            return data 
    278 #         
    279 #        mimetype = kwargs.get('mimetype', self.default_content_type) 
    280 #         
    281 #        if self.original_size or self.max_size: 
    282 #            if not value: 
    283 #                return self.default 
    284 #            w=h=0 
    285 #            if self.max_size: 
    286 #                if value.width > self.max_size[0] or \ 
    287 #                       value.height > self.max_size[1]: 
    288 #                    factor = min(float(self.max_size[0])/float(value.width), 
    289 #                                 float(self.max_size[1])/float(value.height)) 
    290 #                    w = int(factor*value.width) 
    291 #                    h = int(factor*value.height) 
    292 #            elif self.original_size: 
    293 #                w,h = self.original_size 
    294 #            if w and h: 
    295 #                __traceback_info__ = (self, value, w, h) 
    296 #                fvalue, format = self.scale(data, w, h) 
    297 #                data = fvalue.read() 
    298 #        else: 
    299 #            data = str(value.data) 
    300 #             
    301 #        return data 
    302 # 
    303 #    security.declarePrivate('scale') 
    304 #    def scale(self, data, w, h, default_format = 'PNG'): 
    305 #        """ scale image (with material from ImageTag_Hotfix)""" 
    306 #        #make sure we have valid int's 
    307 #        size = int(w), int(h) 
    308 # 
    309 #        original_file=StringIO(data) 
    310 #        image = PIL.Image.open(original_file) 
    311 #        # consider image mode when scaling 
    312 #        # source images can be mode '1','L,','P','RGB(A)' 
    313 #        # convert to greyscale or RGBA before scaling 
    314 #        # preserve palletted mode (but not pallette) 
    315 #        # for palletted-only image formats, e.g. GIF 
    316 #        # PNG compression is OK for RGBA thumbnails 
    317 #        original_mode = image.mode 
    318 #        if original_mode == '1': 
    319 #            image = image.convert('L') 
    320 #        elif original_mode == 'P': 
    321 #            image = image.convert('RGBA') 
    322 #        image.thumbnail(size, self.pil_resize_algo) 
    323 #        # XXX: tweak to make the unit test 
    324 #        #      test_fields.ProcessingTest.test_processing_fieldset run 
    325 #        format = image.format and image.format or default_format 
    326 #        # decided to only preserve palletted mode 
    327 #        # for GIF, could also use image.format in ('GIF','PNG') 
    328 #        if original_mode == 'P' and format == 'GIF': 
    329 #            image = image.convert('P') 
    330 #        thumbnail_file = StringIO() 
    331 #        # quality parameter doesn't affect lossless formats 
    332 #        image.save(thumbnail_file, format, quality=self.pil_quality) 
    333 #        thumbnail_file.seek(0) 
    334 #        return thumbnail_file, format.lower() 
    335 # 
    336  
    337  
    338     security.declareProtected(MODIFY_CONTENT,'createPieces') 
    339     def createPieces(self): 
    340         """ get uploads from form, order them to look like they're coming from SlideWidget and send them to set-method of ChapterField """ 
    341         REQUEST=self.REQUEST 
     348 
    342349        tool = getToolByName(self, REFERENCE_CATALOG) 
    343350        plone_utils = getToolByName(self, 'plone_utils') 
     
    349356        is_edited=False 
    350357        fine_pieces=0 
     358        free_n=1 
    351359         
    352360        for n in range(n_pieces): 
    353361            file = REQUEST.form.get('bodyText_file_%s' % n) 
    354362            if file and hasattr(file, 'filename'):     
    355                 # This is a file, so create a piece from it, get its uid and give that to be the content of this chapter 
    356                 new_piece= lt.createPieceFromFile(file, self) 
    357                 if not new_piece: 
    358                     uid=''                 
    359                 elif not new_piece.isImage(): 
    360                     self.content._delObject(new_piece.id) 
    361                     uid='' 
    362                 else: 
    363                     uid=new_piece.UID() 
    364                 if uid: 
    365                     # store UID in session so that we can edit these new pieces  
    366                     fine_pieces=fine_pieces+1 
    367                     #try to set references 
    368                     __traceback_info__ = (self, uid, targetUIDs) #? is this used 
    369                     if uid not in targetUIDs: 
    370                         tool.addReference(self, uid, 'uses', **{'referenceClass' : Reference}) 
     363                # This is a file, so create copies of it to file system 
     364                (filename, free_n)= self.createExternalImages(file, free_n) 
     365                fine_pieces+=1 
    371366                #put chapter where it belongs 
    372367                if len(chapters)>n*2: 
    373                     chapters[n*2]=(uid,'image_piece') 
     368                    chapters[n*2]=(filename,'image_piece') 
    374369                else: 
    375370                    while len(chapters)<=(n-1)*2: 
     
    389384        return is_edited 
    390385 
     386 
    391387    def deleteResource(self, reason=''): 
    392388        fields = self.getBodyText() 
  • trunk/skins/lemill/portlet_piece_actions.pt

    r2204 r2378  
    3030            </li> 
    3131            <li><a href="" i18n:translate="label_view_history" tal:attributes="href string:${here_url}/history_view">History</a></li> 
     32            <li tal:condition="python:can_moderate and context.portal_type=='LeMillReference'">    
     33               <a href="" tal:attributes="href string:${here_url}/manage_convert" class="deleteLinkColor"><tal:block>Convert resource</tal:block>...</a> 
     34            </li> 
     35 
     36 
    3237            <li tal:condition="python:is_owner or can_moderate"> 
    3338               <a href="" i18n:domain="plone" tal:attributes="href string:${here_url}/delete" class="deleteLinkColor"><tal:block i18n:translate="Delete">Delete</tal:block>...</a> 
Note: See TracChangeset for help on using the changeset viewer.