source: ZMS/trunk/_mediadb.py @ 1780

Revision 1780, 15.6 KB checked in by zmsdev, 7 weeks ago (diff)

applied fix for media-folder: link-elements may cause infinite loop (requested by desy).

Line 
1################################################################################
2# _mediadb.py
3#
4# This program is free software; you can redistribute it and/or
5# modify it under the terms of the GNU General Public License
6# as published by the Free Software Foundation; either version 2
7# of the License, or (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program; if not, write to the Free Software
16# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17################################################################################
18
19# Imports.
20from App.special_dtml import HTMLFile
21from Persistence import Persistent
22from ZPublisher.Iterators import filestream_iterator
23import OFS.SimpleItem
24import Acquisition
25import os
26import urllib
27import time
28# Product Imports.
29import _blobfields
30import _fileutil
31import _globals
32import _objattrs
33
34
35"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
36Constructor
37"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
38def manage_addMediaDb(self, location, REQUEST=None, RESPONSE=None):
39  """ manage_addMediaDb """
40  obj = MediaDb(location)
41  self._setObject(obj.id, obj)
42  recurse_addMediaDb(self,self.getMediaDb())
43  if RESPONSE is not None:
44    RESPONSE.redirect('%s/manage_main'%self.absolute_url())
45
46
47def containerFilter(container):
48  return container.meta_type == 'ZMS'
49
50
51################################################################################
52###   
53###   Create
54###   
55################################################################################
56def recurse_addMediaDb(self, mediadb):
57
58  # Process recordset.
59  if self.getType()=='ZMSRecordSet':
60    key = self.getMetaobjAttrIds(self.meta_id)[0]
61    obj_attr = self.getObjAttr(key)
62    for lang in self.getLangIds():
63      for obj_vers in self.getObjVersions():
64        v = _objattrs.getobjattr(self,obj_vers,obj_attr,lang)
65        c = 0
66        for r in v:
67          for k in r.keys():
68            u = r[k]
69            if getattr(u,'__class_name__',None) in [_blobfields.MyImage.__class_name__, _blobfields.MyFile.__class_name__]:
70              mediadbfile = mediadb.storeFile(u)
71              u.mediadbfile = mediadbfile
72              u.data = ''
73          c += 1
74 
75  # Process object.
76  else:
77    for key in self.getObjAttrs().keys():
78      obj_attr = self.getObjAttr(key)
79      datatype = obj_attr['datatype_key']
80      if datatype in _globals.DT_BLOBS:
81        for lang in self.getLangIds():
82          for obj_vers in self.getObjVersions():
83            v = _objattrs.getobjattr(self,obj_vers,obj_attr,lang)
84            if v is not None and getattr(v,'__class_name__',None) in [_blobfields.MyImage.__class_name__, _blobfields.MyFile.__class_name__]:
85              mediadbfile = mediadb.storeFile(v)
86              v.mediadbfile = mediadbfile
87              v.data = ''
88              _objattrs.setobjattr(self,obj_vers,obj_attr,v,lang)
89 
90  # Process children.
91  for ob in self.objectValues( self.dGlobalAttrs.keys()):
92    recurse_addMediaDb(ob,mediadb)
93
94
95################################################################################
96###   
97###   Compress
98###   
99################################################################################
100def getFilenamesFromValue( v):
101  rtn = []
102  if type( v) is list:
103    for i in v:
104      rtn.extend( getFilenamesFromValue( i))
105  elif type( v) is dict:
106    for k in v.keys():
107      rtn.extend( getFilenamesFromValue( v[k]))
108  elif isinstance(v,_blobfields.MyImage) or isinstance(v,_blobfields.MyFile):
109    filename = v.getMediadbfile()
110    if filename is not None:
111      rtn.append( v.getMediadbfile())
112  return rtn
113
114def manage_packMediaDb(self, REQUEST=None, RESPONSE=None):
115  """ manage_packMediaDb """
116  message = ''
117  c = 0
118  t = 0
119  mediadb = self.getMediaDb()
120  path = mediadb.location
121  filenames = mediadb.valid_filenames()
122  for filename in os.listdir(path):
123    if filename not in filenames:
124      filepath = path + os.sep + filename
125      if os.path.isfile(filepath):
126        os.remove(filepath)
127        c += 1
128    t += 1
129 
130  # Debug.
131  _globals.writeLog( self, "[manage_packMediaDb]: files deleted %s"%str(filenames))
132 
133  # Return with message.
134  message = 'Packed Media-Folder: %i files (total %i) deleted.'%(c,t)
135  return message
136
137
138################################################################################
139###   
140###   Destroy
141###   
142################################################################################
143def recurse_delMediaDb(self, mediadb):
144  #++ print "[%s.recurse_delMediaDb]:"%(self.meta_id)
145
146  # Process recordset.
147  if self.getType()=='ZMSRecordSet':
148    key = self.getMetaobjAttrIds(self.meta_id)[0]
149    obj_attr = self.getObjAttr(key)
150    for lang in self.getLangIds():
151      for obj_vers in self.getObjVersions():
152        v = _objattrs.getobjattr(self,obj_vers,obj_attr,lang)
153        for r in v:
154          for k in r.keys():
155            u = r[k]
156            mediadbfile = getattr(v,'mediadbfile',None)
157            if mediadbfile is not None:
158              u.mediadbfile = None
159              u.data = mediadb.retrieveFile(mediadbfile)
160  # Process object.
161  else:
162    for key in self.getObjAttrs().keys():
163      obj_attr = self.getObjAttr(key)
164      datatype = obj_attr['datatype_key']
165      if datatype in _globals.DT_BLOBS:
166        for lang in self.getLangIds():
167          for obj_vers in self.getObjVersions():
168            v = _objattrs.getobjattr(self,obj_vers,obj_attr,lang)
169            if v is not None:
170              mediadbfile = getattr(v,'mediadbfile',None)
171              if mediadbfile is not None:
172                v.mediadbfile = None
173                v.data = mediadb.retrieveFile(mediadbfile)
174                _objattrs.setobjattr(self,obj_vers,obj_attr,v,lang)
175 
176  # Process children.
177  if self.meta_id != 'ZMSLinkElement':
178    for ob in self.getChildNodes():
179      recurse_delMediaDb(ob,mediadb)
180
181
182def manage_delMediaDb(self, REQUEST=None, RESPONSE=None):
183  """ manage_delMediaDb """
184  message = ''
185  recurse_delMediaDb(self,self.getMediaDb())
186  self.manage_delObjects(ids=['acl_mediadb'])
187  return message
188
189
190"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
191Class
192"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
193class MediaDb(
194      OFS.SimpleItem.Item,
195      Persistent,
196      Acquisition.Implicit):
197
198    # Properties.
199    # -----------
200    meta_type = 'MediaDb'
201
202    # Management Options.
203    # -------------------
204    manage_options = (
205      {'label': 'Edit','action': 'manage_browse'},
206      {'label': 'Properties','action': 'manage_properties'},
207      )
208
209    # Management Interface.
210    # ---------------------
211    manage_index_html = HTMLFile('dtml/acl_mediadb/manage_index', globals())
212    manage_browse = HTMLFile('dtml/acl_mediadb/manage_browse', globals())
213    manage_properties = HTMLFile('dtml/acl_mediadb/manage_properties', globals())
214
215
216    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
217    Constructor
218    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
219    def __init__(self, location):
220      self.id = 'acl_mediadb'
221      self.location = location
222      _fileutil.mkDir(location)
223
224
225    # --------------------------------------------------------------------------
226    #  MediaDb.urlQuote
227    # --------------------------------------------------------------------------
228    def urlQuote(self, s):
229      return urllib.quote(s)
230
231    # --------------------------------------------------------------------------
232    #  MediaDb.getPath
233    # --------------------------------------------------------------------------
234    def getPath(self, REQUEST):
235      path = REQUEST.get('path','')
236      if len(path) < len(self.location):
237        path = self.location
238      return path
239
240    # --------------------------------------------------------------------------
241    #   MediaDb.readDir
242    # --------------------------------------------------------------------------
243    def readDir(self, path):
244      return _fileutil.readDir(path)
245
246    # --------------------------------------------------------------------------
247    #  MediaDb.getParentDir
248    # --------------------------------------------------------------------------
249    def getParentDir(self, path):
250      return _fileutil.getFilePath(path)
251
252    # --------------------------------------------------------------------------
253    #  MediaDb.getDateStr
254    # --------------------------------------------------------------------------
255    def getDateStr(self, tTime, sFmt='DATETIME_FMT'):
256      dateFmt = {
257          'TIME_FMT':'%H:%M:%S',
258          'DATE_FMT':'%Y/%m/%d',
259          'DATETIME_FMT':'%Y/%m/%d %H:%M:%S',
260         }
261      try:
262        s = time.strftime(dateFmt[sFmt],time.localtime(tTime))
263      except:
264        s = str(tTime)
265      return s
266
267
268    # --------------------------------------------------------------------------
269    #  MediaDb.getDataSizeStr
270    # --------------------------------------------------------------------------
271    def getDataSizeStr(self, len):
272      return _fileutil.getDataSizeStr(len)
273
274
275    # --------------------------------------------------------------------------
276    #  MediaDb.getFile
277    # --------------------------------------------------------------------------
278    def getFile(self, REQUEST,RESPONSE):
279      filename = _fileutil.extractFilename( self.getPath( REQUEST))
280      RESPONSE.setHeader('Content-Type','Unknown')
281      RESPONSE.setHeader('Content-Disposition','inline;filename="%s"'%filename)
282      return self.retrieveFileStreamIterator( filename, REQUEST)
283
284
285    # --------------------------------------------------------------------------
286    #   MediaDb.storeFile
287    # --------------------------------------------------------------------------
288    def storeFile(self, file):
289      filename = _fileutil.extractFilename(file.filename)
290      if len( filename) > 0:
291        fileext = _fileutil.extractFileExt(file.filename)
292        filename = filename[:-(len(fileext)+1)] + '_' + str(time.time()).replace('.','') + '.' + fileext
293        filepath = _fileutil.getOSPath('%s/%s'%(self.location,filename))
294        _fileutil.exportObj(file,filepath)
295      return filename
296
297
298    # --------------------------------------------------------------------------
299    #   MediaDb.retrieveFileStreamIterator
300    # --------------------------------------------------------------------------
301    def retrieveFileStreamIterator(self, filename, REQUEST=None):
302      threshold = 2 << 16 # 128 kb
303      local_filename = _fileutil.getOSPath('%s/%s'%(self.location,filename))
304      fsize = os.path.getsize( local_filename)
305      REQUEST.RESPONSE.setHeader( 'content-length' ,fsize)
306      if fsize < threshold or REQUEST.RESPONSE is None:
307        try:
308          f = open( local_filename, 'rb')
309          data = f.read()
310        finally:
311          f.close()
312      else:
313        data = filestream_iterator( local_filename, 'rb')
314      return data
315
316
317    # --------------------------------------------------------------------------
318    #   MediaDb.retrieveFile
319    # --------------------------------------------------------------------------
320    def retrieveFile(self, filename):
321      try:
322        local_filename = _fileutil.getOSPath('%s/%s'%(self.location,filename))
323        f = open( local_filename, 'rb')
324        data = f.read()
325        f.close()
326      except:
327        data = ''
328      return data
329
330
331    # --------------------------------------------------------------------------
332    #   MediaDb.getFileSize
333    # --------------------------------------------------------------------------
334    def getFileSize(self, filename):
335      local_filename = _fileutil.getOSPath('%s/%s'%(self.location,filename))
336      fsize = os.path.getsize( local_filename)
337      return fsize
338
339
340    # --------------------------------------------------------------------------
341    #   MediaDb.destroyFile
342    # --------------------------------------------------------------------------
343    def destroyFile(self, filename):
344      try:
345        filepath = _fileutil.getOSPath('%s/%s'%(self.location,filename))
346        _fileutil.remove(filepath)
347      except:
348        pass
349
350
351    # --------------------------------------------------------------------------
352    #  MediaDb.valid_filenames
353    # --------------------------------------------------------------------------
354    def valid_filenames(self):
355      filenames = []
356      objs = [self.getSelf()]
357      objs.extend(objs[0].getTreeNodes())
358      objs.extend(objs[0].getTrashcan().getTreeNodes())
359      for obj in objs:
360        # Process recordset.
361        if obj.getType()=='ZMSRecordSet':
362          si = obj.getMetaobjAttrIds(obj.meta_id)[0]
363          obj_attr = obj.getObjAttr(si)
364          for lang in obj.getLangIds():
365            for obj_vers in obj.getObjVersions():
366              v = _objattrs.getobjattr(obj,obj_vers,obj_attr,lang)
367              for r in v:
368                for k in r.keys():
369                  u = r[k]
370                  mediadbfile = getattr(u,'mediadbfile',None)
371                  if mediadbfile is not None:
372                    filenamesFromValue = getFilenamesFromValue( u)
373                    for filename in filenamesFromValue:
374                      if filename not in filenames:
375                        filenames.append( filename)
376        # Process object.
377        else:
378          obj_attrs = obj.getObjAttrs()
379          for si in obj_attrs.keys():
380            obj_attr = obj_attrs[si]
381            datatype = obj_attr['datatype']
382            multilang = obj_attr['multilang']
383            if datatype in [ 'file', 'image', 'list', 'dictionary']:
384              for obj_vers in obj.getObjVersions():
385                obj_attr_names = []
386                if multilang:
387                  for lang in self.getLangIds():
388                    obj_attr_names.append('%s_%s'%(si,lang))
389                else:
390                  obj_attr_names.append(si)
391                for obj_attr_name in obj_attr_names:
392                  v = getattr(obj_vers,obj_attr_name,None)
393                  filenamesFromValue = getFilenamesFromValue( v)
394                  for filename in filenamesFromValue:
395                    if filename not in filenames:
396                      filenames.append( filename)
397      return filenames
398
399
400    """
401    ############################################################################
402    ###
403    ###   P r o p e r t i e s
404    ###
405    ############################################################################
406    """
407
408    ############################################################################
409    #  MediaDb.manage_changeProperties:
410    #
411    #  Change MediaDb properties.
412    ############################################################################
413    def manage_changeProperties(self, submit, REQUEST, RESPONSE):
414      """ MediaDb.manage_changeProperties """
415     
416      message = ''
417
418      # Change.
419      if submit == 'Change':
420        self.location = REQUEST.get('location',self.location)
421       
422      # Return.
423      if RESPONSE is not None:
424        RESPONSE.redirect('manage_properties?manage_tabs_message=%s'%urllib.quote(message))
425
426################################################################################
Note: See TracBrowser for help on using the repository browser.