1919import tempfile
2020from zipfile import ZipFile
2121
22- from PyQt4 import QtGui , QtCore , QtXml , uic
22+ # from PyQt4 import QtGui, QtCore, QtXml, uic
23+ from PyQt5 import QtGui , QtCore , uic , QtXml , QtWidgets
24+ from PyQt5 .QtCore import *
2325
24- from about import DialogAbout
25- from convert import DialogConvert
26- from image import ImageFlags
27- from options import DialogOptions
28- import util
26+ from . about import DialogAbout
27+ from . convert import DialogConvert
28+ from . image import ImageFlags
29+ from . options import DialogOptions
30+ from . import util
2931
3032
31- # Sort function use to sort files in a natural order, by lowering
32- # characters, and manage multi levels of integers (tome 1/ page 1.jpg, etc etc)
33+ # Sort function used to sort files in a natural order, by lowering
34+ # characters, and managing multi levels of integers (tome 1/ page 1.jpg, etc etc)
3335# cf: See http://www.codinghorror.com/blog/archives/001018.html
3436def natural_key (string_ ):
3537 l = []
36- for s in re .split (r'(\d+)' , string_ ):
37- # QString do not have isdigit, so convert it if need
38- if isinstance (s , QtCore .QString ):
39- s = unicode (s )
40- if s .isdigit ():
41- l .append (int (s ))
42- else :
43- l .append (s .lower ())
38+ print (f"string_ => { string_ } " )
39+ print (f"type(string_) => { type (string_ )} " )
40+ if string_ :
41+ for s in re .split (r'(\d+)' , string_ ):
42+ # str does not have isdigit, so convert it if needed
43+ if isinstance (s , str ):
44+ s = str (s )
45+ if s .isdigit ():
46+ l .append (int (s ))
47+ else :
48+ l .append (s .lower ())
4449 return l
4550
4651
@@ -80,35 +85,39 @@ def save(self, filename):
8085 root .appendChild (itemImg )
8186 itemImg .setAttribute ('filename' , filenameImg )
8287
83- textXml = document .toString (4 ).toUtf8 ()
88+ textXml = document .toString (4 )
89+
90+ if len (filename ) == 2 :
91+ filename = filename [0 ] # filename received is a tuple: get the first item
8492
8593 try :
86- fileXml = open (unicode (filename ), 'w' )
94+ fileXml = open (str (filename ), 'w' )
8795 fileXml .write (textXml )
8896 fileXml .close ()
89- except IOError :
90- raise RuntimeError ('Cannot create book file %s' % filename )
97+ except IOError as ioe :
98+ print (f"IOError caught =>\n { ioe } " )
99+ raise RuntimeError (f'Can\' t save file { filename } ' )
91100
92101 self .filename = filename
93102 self .modified = False
94103
95104
96105 def load (self , filename ):
97106 try :
98- fileXml = open (unicode (filename ), 'r' )
107+ fileXml = open (str (filename ), 'r' )
99108 textXml = fileXml .read ()
100109 fileXml .close ()
101110 except IOError :
102- raise RuntimeError ('Cannot open book file %s' % filename )
111+ raise RuntimeError (f'Can \' t open Mangle file { filename } ' )
103112
104113 document = QtXml .QDomDocument ()
105114
106- if not document .setContent (QtCore . QString . fromUtf8 ( textXml ) ):
107- raise RuntimeError ('Error parsing book file %s' % filename )
115+ if not document .setContent (textXml ):
116+ raise RuntimeError (f 'Error parsing Mangle file { filename } ' )
108117
109118 root = document .documentElement ()
110119 if root .tagName () != 'book' :
111- raise RuntimeError ('Unexpected book format in file %s' % filename )
120+ raise RuntimeError (f 'Unexpected Mangle format in file { filename } ' )
112121
113122 self .title = root .attribute ('title' , 'Untitled' )
114123 self .overwrite = root .attribute ('overwrite' , 'true' if Book .DefaultOverwrite else 'false' ) == 'true'
@@ -123,15 +132,15 @@ def load(self, filename):
123132 if items is None :
124133 return
125134
126- for i in xrange (0 , len (items )):
135+ for i in range (0 , len (items )):
127136 item = items .at (i ).toElement ()
128137 if item .hasAttribute ('filename' ):
129138 self .images .append (item .attribute ('filename' ))
130139
131140
132- class MainWindowBook (QtGui .QMainWindow ):
141+ class MainWindowBook (QtWidgets .QMainWindow ):
133142 def __init__ (self , filename = None ):
134- QtGui .QMainWindow .__init__ (self )
143+ QtWidgets .QMainWindow .__init__ (self )
135144
136145 uic .loadUi (util .buildResPath ('mangle/ui/book.ui' ), self )
137146 self .listWidgetFiles .setContextMenuPolicy (QtCore .Qt .CustomContextMenu )
@@ -174,7 +183,7 @@ def dropEvent(self, event):
174183 filename = url .toLocalFile ()
175184 if self .isImageFile (filename ):
176185 filenames .append (filename )
177- elif os .path .isdir (unicode (filename )):
186+ elif os .path .isdir (str (filename )):
178187 directories .append (filename )
179188
180189 self .addImageDirs (directories )
@@ -191,12 +200,14 @@ def onFileOpen(self):
191200 if not self .saveIfNeeded ():
192201 return
193202
194- filename = QtGui .QFileDialog .getOpenFileName (
203+ filename = QtWidgets .QFileDialog .getOpenFileName (
195204 parent = self ,
196205 caption = 'Select a book file to open' ,
197206 filter = 'Mangle files (*.mngl);;All files (*.*)'
198207 )
199- if not filename .isNull ():
208+ filename = filename [0 ] # first item is filename (second is filter)
209+
210+ if filename :
200211 self .loadBook (self .cleanupBookFile (filename ))
201212
202213
@@ -209,7 +220,7 @@ def onFileSaveAs(self):
209220
210221
211222 def onFilesContextMenu (self , point ):
212- menu = QtGui .QMenu (self )
223+ menu = QtWidgets .QMenu (self )
213224 menu .addAction (self .menu_Add .menuAction ())
214225
215226 if len (self .listWidgetFiles .selectedItems ()) > 0 :
@@ -225,21 +236,23 @@ def onFilesDoubleClick(self, item):
225236
226237
227238 def onBookAddFiles (self ):
228- filenames = QtGui .QFileDialog .getOpenFileNames (
239+ filenames = QtWidgets .QFileDialog .getOpenFileNames (
229240 parent = self ,
230241 caption = 'Select image file(s) to add' ,
231242 filter = 'Image files (*.jpeg *.jpg *.gif *.png);;Comic files (*.cbz)'
232243 )
244+ filenames = filenames [0 ] # get first tuple item (second is file filter)
245+
233246 if (self .containsCbzFile (filenames )):
234247 self .addCBZFiles (filenames )
235248 else :
236249 self .addImageFiles (filenames )
237250
238251
239252 def onBookAddDirectory (self ):
240- directory = QtGui .QFileDialog .getExistingDirectory (self , 'Select an image directory to add' )
241- if not directory . isNull () :
242- self .book .title = os .path .basename (os .path .normpath (unicode (directory )))
253+ directory = QtWidgets .QFileDialog .getExistingDirectory (self , 'Select an image directory to add' )
254+ if directory :
255+ self .book .title = os .path .basename (os .path .normpath (str (directory )))
243256 self .addImageDirs ([directory ])
244257
245258
@@ -257,24 +270,24 @@ def onBookRemove(self):
257270
258271 def onBookOptions (self ):
259272 dialog = DialogOptions (self , self .book )
260- if dialog .exec_ () == QtGui .QDialog .Accepted :
273+ if dialog .exec_ () == QtWidgets .QDialog .Accepted :
261274 self .book .titleSet = True
262275
263276
264277 def onBookExport (self ):
265278 if len (self .book .images ) == 0 :
266- QtGui .QMessageBox .warning (self , 'Mangle' , 'This book has no images to export' )
279+ QtWidgets .QMessageBox .warning (self , 'Mangle' , 'This book has no images to export' )
267280 return
268281
269282 if not self .book .titleSet : # if self.book.title is None:
270283 dialog = DialogOptions (self , self .book )
271- if dialog .exec_ () == QtGui .QDialog .Rejected :
284+ if dialog .exec_ () == QtWidgets .QDialog .Rejected :
272285 return
273286 else :
274287 self .book .titleSet = True
275288
276- directory = QtGui .QFileDialog .getExistingDirectory (self , 'Select a directory to export book to' )
277- if not directory . isNull () :
289+ directory = QtWidgets .QFileDialog .getExistingDirectory (self , 'Select a directory to export book to' )
290+ if directory :
278291 dialog = DialogConvert (self , self .book , directory )
279292 dialog .exec_ ()
280293
@@ -293,40 +306,40 @@ def saveIfNeeded(self):
293306 if not self .book .modified :
294307 return True
295308
296- result = QtGui .QMessageBox .question (
309+ result = QtWidgets .QMessageBox .question (
297310 self ,
298311 'Mangle' ,
299312 'Save changes to the current book?' ,
300- QtGui .QMessageBox .Yes | QtGui .QMessageBox .No | QtGui .QMessageBox .Cancel ,
301- QtGui .QMessageBox .Yes
313+ QtWidgets .QMessageBox .Yes | QtWidgets .QMessageBox .No | QtWidgets .QMessageBox .Cancel ,
314+ QtWidgets .QMessageBox .Yes
302315 )
303316
304317 return (
305- result == QtGui .QMessageBox .No or
306- result == QtGui .QMessageBox .Yes and self .saveBook ()
318+ result == QtWidgets .QMessageBox .No or
319+ result == QtWidgets .QMessageBox .Yes and self .saveBook ()
307320 )
308321
309322
310323 def saveBook (self , browse = False ):
311324 if self .book .title is None :
312- QtGui .QMessageBox .warning (self , 'Mangle' , 'You must specify a title for this book before saving' )
325+ QtWidgets .QMessageBox .warning (self , 'Mangle' , 'You must specify a title for this book before saving' )
313326 return False
314327
315328 filename = self .book .filename
316329 if filename is None or browse :
317- filename = QtGui .QFileDialog .getSaveFileName (
330+ filename = QtWidgets .QFileDialog .getSaveFileName (
318331 parent = self ,
319332 caption = 'Select a book file to save as' ,
320333 filter = 'Mangle files (*.mngl);;All files (*.*)'
321334 )
322- if filename . isNull () :
335+ if not filename :
323336 return False
324337 filename = self .cleanupBookFile (filename )
325338
326339 try :
327340 self .book .save (filename )
328- except RuntimeError , error :
329- QtGui .QMessageBox .critical (self , 'Mangle' , str (error ))
341+ except RuntimeError as error :
342+ QtWidgets .QMessageBox .critical (self , 'Mangle' , str (error ))
330343 return False
331344
332345 return True
@@ -335,8 +348,8 @@ def saveBook(self, browse=False):
335348 def loadBook (self , filename ):
336349 try :
337350 self .book .load (filename )
338- except RuntimeError , error :
339- QtGui .QMessageBox .critical (self , 'Mangle' , str (error ))
351+ except RuntimeError as error :
352+ QtWidgets .QMessageBox .critical (self , 'Mangle' , str (error ))
340353 else :
341354 self .listWidgetFiles .clear ()
342355 for image in self .book .images :
@@ -380,13 +393,15 @@ def removeImageFiles(self):
380393
381394 def addImageFiles (self , filenames ):
382395 filenamesListed = []
383- for i in xrange (0 , self .listWidgetFiles .count ()):
396+ for i in range (0 , self .listWidgetFiles .count ()):
384397 filenamesListed .append (self .listWidgetFiles .item (i ).text ())
385-
398+
386399 # Get files but in a natural sorted order
387- for filename in sorted (filenames , key = natural_key ):
400+ sorted_filenames = sorted (filenames , key = natural_key )
401+
402+ for filename in sorted_filenames :
388403 if filename not in filenamesListed :
389- filename = QtCore . QString (filename )
404+ filename = str (filename )
390405 self .listWidgetFiles .addItem (filename )
391406 self .book .images .append (filename )
392407 self .book .modified = True
@@ -396,12 +411,12 @@ def addImageDirs(self, directories):
396411 filenames = []
397412
398413 for directory in directories :
399- for root , _ , subfiles in os .walk (unicode (directory )):
414+ for root , _ , subfiles in os .walk (str (directory )):
400415 for filename in subfiles :
401416 path = os .path .join (root , filename )
402417 if self .isImageFile (path ):
403418 filenames .append (path )
404-
419+
405420 self .addImageFiles (filenames )
406421
407422
@@ -411,7 +426,7 @@ def addCBZFiles(self, filenames):
411426 filenames .sort ()
412427
413428 filenamesListed = []
414- for i in xrange (0 , self .listWidgetFiles .count ()):
429+ for i in range (0 , self .listWidgetFiles .count ()):
415430 filenamesListed .append (self .listWidgetFiles .item (i ).text ())
416431
417432 for filename in filenames :
@@ -426,15 +441,15 @@ def addCBZFiles(self, filenames):
426441 pass # the dir exists so we are going to extract the images only.
427442 else :
428443 cbzFile .extract (f , path )
429- if os .path .isdir (unicode (path )): # Add the directories
444+ if os .path .isdir (str (path )): # Add the directories
430445 directories .append (path )
431446
432447 self .addImageDirs (directories ) # Add the files
433448
434449
435450 def isImageFile (self , filename ):
436451 imageExts = ['.jpeg' , '.jpg' , '.gif' , '.png' ]
437- filename = unicode (filename )
452+ filename = str (filename )
438453 return (
439454 os .path .isfile (filename ) and
440455 os .path .splitext (filename )[1 ].lower () in imageExts
@@ -443,7 +458,7 @@ def isImageFile(self, filename):
443458 def containsCbzFile (self , filenames ):
444459 cbzExts = ['.cbz' ]
445460 for filename in filenames :
446- filename = unicode (filename )
461+ filename = str (filename )
447462 result = (
448463 os .path .isfile (filename ) and
449464 os .path .splitext (filename )[1 ].lower () in cbzExts
@@ -453,6 +468,6 @@ def containsCbzFile(self, filenames):
453468 return False
454469
455470 def cleanupBookFile (self , filename ):
456- if len (os .path .splitext (unicode (filename ))[1 ]) == 0 :
471+ if len (os .path .splitext (str (filename ))[1 ]) == 0 :
457472 filename += '.mngl'
458473 return filename
0 commit comments