| 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.
|
|---|
| 20 | from App.special_dtml import HTMLFile
|
|---|
| 21 | from Persistence import Persistent
|
|---|
| 22 | from ZPublisher.Iterators import filestream_iterator
|
|---|
| 23 | import OFS.SimpleItem
|
|---|
| 24 | import Acquisition
|
|---|
| 25 | import os
|
|---|
| 26 | import urllib
|
|---|
| 27 | import time
|
|---|
| 28 | # Product Imports.
|
|---|
| 29 | import _blobfields
|
|---|
| 30 | import _fileutil
|
|---|
| 31 | import _globals
|
|---|
| 32 | import _objattrs
|
|---|
| 33 |
|
|---|
| 34 |
|
|---|
| 35 | """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
|---|
| 36 | Constructor
|
|---|
| 37 | """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
|---|
| 38 | def 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 |
|
|---|
| 47 | def containerFilter(container):
|
|---|
| 48 | return container.meta_type == 'ZMS'
|
|---|
| 49 |
|
|---|
| 50 |
|
|---|
| 51 | ################################################################################
|
|---|
| 52 | ###
|
|---|
| 53 | ### Create
|
|---|
| 54 | ###
|
|---|
| 55 | ################################################################################
|
|---|
| 56 | def 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 | ################################################################################
|
|---|
| 100 | def 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 |
|
|---|
| 114 | def 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 | ################################################################################
|
|---|
| 143 | def 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 |
|
|---|
| 182 | def 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 | """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
|---|
| 191 | Class
|
|---|
| 192 | """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
|---|
| 193 | class 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 | ################################################################################
|
|---|