source: trunk/Piece.py @ 1285

Revision 1285, 7.7 KB checked in by jukka, 13 years ago (diff)

Fixed #1094 and #1100. Deleted some broken pieces from lemill.net and upgrade-script seems to run fine.

  • Property svn:eol-style set to native
Line 
1# Copyright 2006 by the LeMill Team (see AUTHORS)
2#
3# This file is part of LeMill.
4#
5# LeMill is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 2 of the License, or
8# (at your option) any later version.
9#
10# LeMill is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with LeMill; if not, write to the Free Software
17# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
19from SharedMetadata import *
20from Products.Archetypes.public import *
21from Globals import InitializeClass
22from Products.CMFCore.utils import getToolByName
23from AccessControl import ClassSecurityInfo, Unauthorized
24from config import PROJECTNAME, VIEW
25from FieldsWidgets import WYSIWYMField, WYSIWYMWidget
26from Resources import Resource
27from mp3tool import get_length
28import cStringIO
29try:
30    from PIL import Image
31except ImportError:
32    pass
33
34schema = BaseSchema + description + tags + author_schema + original_author_schema + piece_license_schema + coverImage + contentFile + sourceFile + lemill_metadata_mods + deletionReason 
35
36schema = schema + Schema((
37    ImageField('image',
38               required=False,
39               accessor='getImage',
40               mutator='setImage',
41               sizes={'small':(120,120),'medium':(240,240),'large':(500,500)},
42               widget = ImageWidget(visible={'view':'invisible','edit':'invisible'}),
43               ),
44    ImageField('imageJpeg', # required for building Pilot flash animations
45               required=False,
46               default_content_type = 'image/jpeg',
47               allowable_content_types = ('image/jpeg',),
48               original_size=(500,375),
49               widget = ImageWidget(visible={'view':'invisible','edit':'invisible'}),
50               ),
51
52    IntegerField('length',
53               required=False,
54               default=0,
55               widget = LabelWidget(
56                    label = "Playing time",
57                    label_msgid = "label_playing_time",
58                    i18n_domain = "lemill",
59                    visible={'view':'visible', 'edit':'invisible'},
60               ))
61    ))
62
63schema = schema.copy()
64schema.__delitem__('language')
65schema.moveField('rights', pos='bottom')
66
67class Piece(Resource):
68    """Piece"""
69    schema = schema
70
71    actions= (
72    {
73    'id':'edit',
74    'name':'Edit',
75    'action':'string:${object_url}/piece_edit',
76    'permission':('View',),
77    },
78    )
79
80
81    meta_type = "Piece"
82    archetype_name = "Piece"
83    security = ClassSecurityInfo()
84    security.declareObjectPublic()
85
86    aliases = {
87        '(Default)' : 'base_view',
88        'view'      : 'base_view',
89        'edit'      : 'piece_edit'
90    }
91
92       
93    # Use the file as cover image, if it's an image
94    def setFile(self,value,**kwargs):
95        file=self.getField('file')
96        # Call normal mutator for this field
97        file.set(self,value,**kwargs)
98        if file.getContentType(self).startswith('image/'):
99            # Call mutator for the coverImage field as well
100            cover=self.getField('coverImage')
101            cover.set(self,value,**kwargs)
102            # set 'hasCoverImage'-flag
103            has_cover=self.getField('hasCoverImage')
104            has_cover.set(self,True)
105            # Populate the image field
106            image=self.getField('image')
107            image.set(self,value,**kwargs)
108            # we also need 500x500 jpg for every image..
109            #<--comment this out because we don't need to make these until asked with get-method... should speed up updating archetypes.
110            #image_jpeg=self.getField('image_jpeg')
111            #image_jpeg.set(self,value,**kwargs)
112        if file.getContentType(self).startswith('audio/mpeg'):
113            length=self.getField('length')
114            try:
115                length.set(self,self.getMp3Length(), **kwargs)
116            except:
117                print 'something went wrong with setting mp3 length'
118
119
120    def pretty_title_or_id(self):
121        """Return modified title."""
122        return '[P] ' + self.Title()
123
124    def getLength(self):
125        """get stored length of audio piece or try to calculate it """
126        length=self.getField('length').get(self)
127        file=self.getField('file')
128        if length==0 and file.getContentType(self).startswith('audio/mpeg'):
129            length=self.getMp3Length()
130            self.setLength(length)
131        if length==0:
132            return 30
133        else:
134            return length
135           
136
137    def isImage(self):
138        """Returns whether the piece is an image."""
139        file=self.getField('file')
140        return file.getContentType(self).startswith('image/')
141
142    def isAudio(self):
143        """Returns whether the piece is an audio file. """
144        file=self.getField('file')
145        return file.getContentType(self).startswith('audio/')
146
147    def isMovie(self):
148        """Returns whether the piece is an movie file. (not tested) """
149        file=self.getField('file')
150        return file.getContentType(self).startswith('movie/')
151       
152    def getMp3Length(self):
153        """Calling out for our custom mp3tool"""
154        print 'calculating length for mp3 %s' % self.getId()
155        file=self.getField('file')
156        file=file.get(self, raw=True, unwrapped=True)
157        file=file.aq_self
158        file=str(file)
159        try:
160            length=get_length(file)
161        except:
162            length=0
163            print 'calculating mp3 length failed for %s' % self.id
164        return length
165
166
167    def getJpegVarName(self):
168        """ 'image_large' if image is originally jpeg,
169        'image_jpeg' if not (this is special image field, where jpeg version of original is stored)
170        gives strings because these are only parts of urls that are passed to flash """
171        file=self.getField('file')
172        if file==None: return None
173        if not file.getContentType(self).startswith('image/'):
174            print 'why getJpegVarName was called for non-image piece? in %s' % self.getId()
175            return None # this shouldn't happen
176        if file.getContentType(self)=='image/jpeg':
177            return 'image_large'       
178        field=self.getField('imageJpeg')
179        val=self.image_jpeg
180        if len(val)>0 and field.getContentType(self)=='image/jpeg': # not sure about that len
181            return 'imageJpeg'
182        else:
183            value=file.get(self)
184            try:
185                value=self._convertToJpg(value)
186            except:
187                print 'error converting image to jpg'
188                return 'image_large'
189            field.set(self, value)
190            return 'imageJpeg'
191
192    def _convertToJpg(self, value):
193        val = value.data
194        s = cStringIO.StringIO(val)
195        s.seek(0)
196        im = Image.open(s)
197        original_mode = im.mode
198        if original_mode == '1':
199            im = im.convert('L')
200        elif original_mode == 'P':
201            im = im.convert('RGBA')
202        s = cStringIO.StringIO()
203        im.save(s, "jpeg")
204        s.seek(0)
205        value=s.read()
206        return value
207
208    def getDefaultIcon(self, meta_type='', obj=None):
209        """ Names for icons are not anymore algorithmically derived """
210        if self.isAudio():
211            return 'images/default_soundclip.png'
212        elif self.isMovie():
213            return 'images/default_movieclip.png'
214        else:
215            # images should always have coverimages and this method shouldn't even get called
216            return 'images/default_learningresource.png'
217       
218       
219registerType(Piece, PROJECTNAME)
Note: See TracBrowser for help on using the repository browser.