← Back to team overview

openlp-core team mailing list archive

[Merge] lp:~mahfiaz/openlp/media_fixes into lp:openlp

 

mahfiaz has proposed merging lp:~mahfiaz/openlp/media_fixes into lp:openlp.

Requested reviews:
  Tim Bentley (trb143)
Related bugs:
  #730459 Error during saving OOS with non-english names
  https://bugs.launchpad.net/bugs/730459

For more details, see:
https://code.launchpad.net/~mahfiaz/openlp/media_fixes/+merge/52528

A few fixes for mediamanager file handling and service file saving, most notably for #730459, also >2GiB service files are possible, but user is asked if he wants to include >50Mib files.
-- 
https://code.launchpad.net/~mahfiaz/openlp/media_fixes/+merge/52528
Your team OpenLP Core is subscribed to branch lp:openlp.
=== modified file 'openlp/core/lib/mediamanageritem.py'
--- openlp/core/lib/mediamanageritem.py	2011-02-27 06:58:23 +0000
+++ openlp/core/lib/mediamanageritem.py	2011-03-08 09:38:27 +0000
@@ -349,11 +349,11 @@
         Validates whether an image still exists and, if it does, is the
         thumbnail representation of the image up to date.
         """
-        if not os.path.exists(image):
+        if not os.path.exists(unicode(image)):
             return False
         if os.path.exists(thumb):
-            imageDate = os.stat(image).st_mtime
-            thumbDate = os.stat(thumb).st_mtime
+            imageDate = os.stat(unicode(image)).st_mtime
+            thumbDate = os.stat(unicode(thumb)).st_mtime
             # If image has been updated rebuild icon
             if imageDate > thumbDate:
                 self.iconFromFile(image, thumb)

=== modified file 'openlp/core/ui/servicemanager.py'
--- openlp/core/ui/servicemanager.py	2011-03-06 07:59:26 +0000
+++ openlp/core/ui/servicemanager.py	2011-03-08 09:38:27 +0000
@@ -416,45 +416,77 @@
         if not self.fileName():
             return self.saveFileAs()
         else:
-            fileName = self.fileName()
-            log.debug(u'ServiceManager.saveFile - %s' % fileName)
+            path_file_name = unicode(self.fileName())
+            (path, file_name) = os.path.split(path_file_name)
+            basename = file_name[0:file_name.rfind(u'.')-1]
+            service_file_name = basename + '.osd'
+            log.debug(u'ServiceManager.saveFile - %s' % path_file_name)
             SettingsManager.set_last_dir(self.mainwindow.serviceSettingsSection,
-                split_filename(fileName)[0])
+                path)
             service = []
-            serviceFileName = fileName.replace(u'.osz', u'.osd')
             zip = None
-            file = None
             try:
                 write_list = []
-                zip = zipfile.ZipFile(unicode(fileName), 'w')
+                total_size = 0
                 for item in self.serviceItems:
-                    service.append({u'serviceitem': \
+                    service.append({u'serviceitem':
                         item[u'service_item'].get_service_repr()})
                     if item[u'service_item'].uses_file():
                         for frame in item[u'service_item'].get_frames():
                             if item[u'service_item'].is_image():
                                 path_from = frame[u'path']
                             else:
-                                path_from = unicode(os.path.join(
-                                    frame[u'path'],
-                                    frame[u'title']))
-                            # On write a file once
+                                path_from = os.path.join(frame[u'path'],
+                                    frame[u'title'])
+                            # Only write a file once
                             if not path_from in write_list:
-                                write_list.append(path_from)
-                                zip.write(path_from.encode(u'utf-8'))
-                file = open(serviceFileName, u'wb')
-                cPickle.dump(service, file)
-                file.close()
-                zip.write(serviceFileName.encode(u'utf-8'))
+                                file_size = os.path.getsize(path_from)
+                                size_limit = 52428800 # 50MiB
+                                if file_size > size_limit:
+                                    # File exeeds size_limit bytes, ask user
+                                    message = unicode(self.trUtf8('Do you want'
+                                        ' to include \n%.1f MiB file "%s"\n'
+                                        'into the service file?\n'
+                                        'This may take some time.\n\n'
+                                        'Please note that you need to\n'
+                                        'take care of that file yourself.')) %\
+                                        (file_size/1048576,
+                                        os.path.split(path_from)[1])
+                                    ans = QtGui.QMessageBox.question(self,
+                                        self.trUtf8('Including Large File'),
+                                        message,
+                                        QtGui.QMessageBox.StandardButtons(
+                                        QtGui.QMessageBox.Ok|\
+                                        QtGui.QMessageBox.Cancel),
+                                        QtGui.QMessageBox.Ok)
+                                    if ans == QtGui.QMessageBox.Ok:
+                                        write_list.append(path_from)
+                                        total_size += file_size
+                                else:
+                                    write_list.append(path_from)
+                                    total_size += file_size
+                log.debug(u'ServiceManager.saveFile - ZIP contents size is %i'
+                    ' bytes' % total_size)
+                service_content = cPickle.dumps(service)
+                # Usual Zip file cannot exceed 2GiB, file with Zip64 cannot be
+                # extracted using unzip in UNIX.
+                allow_zip_64 = (total_size > 2147483648 + len(service_content))
+                log.debug(u'ServiceManager.saveFile - allowZip64 is %s' %
+                    allow_zip_64)
+                zip = zipfile.ZipFile(path_file_name, 'w', zipfile.ZIP_STORED,
+                    allow_zip_64)
+                # We first add service contents.
+                # We save ALL filenames into ZIP using UTF-8.
+                zip.writestr(service_file_name.encode(u'utf-8'),
+                    service_content)
+                # Finally add all the listed media files.
+                for path_from in write_list:
+                    zip.write(path_from, path_from.encode(u'utf-8'))
+                zip.close()
             except IOError:
                 log.exception(u'Failed to save service to disk')
-            finally:
-                if file:
-                    file.close()
-                if zip:
-                    zip.close()
-            delete_file(serviceFileName)
-            self.mainwindow.addRecentFile(fileName)
+                return False
+            self.mainwindow.addRecentFile(path_file_name)
             self.setModified(False)
         return True
 


Follow ups