Merge branch 'comictagger:develop' into natsort_fix
This commit is contained in:
commit
220606a046
@ -14,6 +14,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import py7zr
|
||||
import zipfile
|
||||
import os
|
||||
import struct
|
||||
@ -50,6 +51,109 @@ class MetaDataStyle:
|
||||
COMET = 2
|
||||
name = ['ComicBookLover', 'ComicRack', 'CoMet']
|
||||
|
||||
class SevenZipArchiver:
|
||||
|
||||
"""7Z implementation"""
|
||||
|
||||
def __init__(self, path):
|
||||
self.path = path
|
||||
|
||||
# @todo: Implement Comment?
|
||||
def getArchiveComment(self):
|
||||
return ""
|
||||
|
||||
def setArchiveComment(self, comment):
|
||||
return False
|
||||
|
||||
def readArchiveFile(self, archive_file):
|
||||
data = ""
|
||||
try:
|
||||
with py7zr.SevenZipFile(self.path, 'r') as zf:
|
||||
data = zf.read(archive_file)[archive_file].read()
|
||||
except py7zr.Bad7zFile as e:
|
||||
print("bad 7zip file [{0}]: {1} :: {2}".format(e, self.path,
|
||||
archive_file), file=sys.stderr)
|
||||
raise IOError
|
||||
except Exception as e:
|
||||
print("bad 7zip file [{0}]: {1} :: {2}".format(e, self.path,
|
||||
archive_file), file=sys.stderr)
|
||||
raise IOError
|
||||
|
||||
return data
|
||||
|
||||
def removeArchiveFile(self, archive_file):
|
||||
try:
|
||||
self.rebuildSevenZipFile([archive_file])
|
||||
except:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def writeArchiveFile(self, archive_file, data):
|
||||
# At the moment, no other option but to rebuild the whole
|
||||
# zip archive w/o the indicated file. Very sucky, but maybe
|
||||
# another solution can be found
|
||||
try:
|
||||
files = self.getArchiveFilenameList()
|
||||
if archive_file in files:
|
||||
self.rebuildSevenZipFile([archive_file])
|
||||
|
||||
# now just add the archive file as a new one
|
||||
with py7zr.SevenZipFile(self.path, 'a') as zf:
|
||||
zf.writestr(data, archive_file)
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
def getArchiveFilenameList(self):
|
||||
try:
|
||||
with py7zr.SevenZipFile(self.path, 'r') as zf:
|
||||
namelist = zf.getnames()
|
||||
|
||||
return namelist
|
||||
except Exception as e:
|
||||
print("Unable to get zipfile list [{0}]: {1}".format(
|
||||
e, self.path), file=sys.stderr)
|
||||
return []
|
||||
|
||||
def rebuildSevenZipFile(self, exclude_list):
|
||||
"""Zip helper func
|
||||
|
||||
This recompresses the zip archive, without the files in the exclude_list
|
||||
"""
|
||||
tmp_fd, tmp_name = tempfile.mkstemp(dir=os.path.dirname(self.path))
|
||||
os.close(tmp_fd)
|
||||
|
||||
try:
|
||||
with py7zr.SevenZipFile(self.path, 'r') as zip:
|
||||
targets = [f for f in zip.getnames() if f not in exclude_list]
|
||||
with py7zr.SevenZipFile(self.path, 'r') as zin:
|
||||
with py7zr.SevenZipFile(tmp_name, 'w') as zout:
|
||||
for fname, bio in zin.read(targets).items():
|
||||
zout.writef(bio, fname)
|
||||
except Exception as e:
|
||||
print("Exception[{0}]: {1}".format(e, self.path))
|
||||
return []
|
||||
|
||||
# replace with the new file
|
||||
os.remove(self.path)
|
||||
os.rename(tmp_name, self.path)
|
||||
|
||||
def copyFromArchive(self, otherArchive):
|
||||
"""Replace the current zip with one copied from another archive"""
|
||||
try:
|
||||
with py7zr.SevenZipFile(self.path, 'w') as zout:
|
||||
for fname in otherArchive.getArchiveFilenameList():
|
||||
data = otherArchive.readArchiveFile(fname)
|
||||
if data is not None:
|
||||
zout.writestr(data, fname)
|
||||
except Exception as e:
|
||||
print("Error while copying to {0}: {1}".format(
|
||||
self.path, e), file=sys.stderr)
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
class ZipArchiver:
|
||||
|
||||
"""ZIP implementation"""
|
||||
@ -101,7 +205,9 @@ class ZipArchiver:
|
||||
# zip archive w/o the indicated file. Very sucky, but maybe
|
||||
# another solution can be found
|
||||
try:
|
||||
self.rebuildZipFile([archive_file])
|
||||
files = self.getArchiveFilenameList()
|
||||
if archive_file in files:
|
||||
self.rebuildZipFile([archive_file])
|
||||
|
||||
# now just add the archive file as a new one
|
||||
zf = zipfile.ZipFile(
|
||||
@ -173,7 +279,7 @@ class ZipArchiver:
|
||||
|
||||
found = False
|
||||
value = bytearray()
|
||||
|
||||
|
||||
# walk backwards to find the "End of Central Directory" record
|
||||
while (not found) and (-pos != file_length):
|
||||
# seek, relative to EOF
|
||||
@ -270,7 +376,7 @@ class RarArchiver:
|
||||
f.close()
|
||||
|
||||
working_dir = os.path.dirname(os.path.abspath(self.path))
|
||||
|
||||
|
||||
# use external program to write comment to Rar archive
|
||||
proc_args = [self.rar_exe_path,
|
||||
'c',
|
||||
@ -304,7 +410,7 @@ class RarArchiver:
|
||||
while tries < 7:
|
||||
try:
|
||||
tries = tries + 1
|
||||
data = rarc.open(archive_file).read()
|
||||
data = rarc.open(archive_file).read()
|
||||
entries = [(rarc.getinfo(archive_file), data)]
|
||||
|
||||
if entries[0][0].file_size != len(entries[0][1]):
|
||||
@ -530,7 +636,7 @@ class UnknownArchiver:
|
||||
class ComicArchive:
|
||||
logo_data = None
|
||||
class ArchiveType:
|
||||
Zip, Rar, Folder, Pdf, Unknown = list(range(5))
|
||||
SevenZip, Zip, Rar, Folder, Pdf, Unknown = list(range(6))
|
||||
|
||||
def __init__(self, path, rar_exe_path=None, default_image_path=None):
|
||||
self.path = path
|
||||
@ -558,7 +664,11 @@ class ComicArchive:
|
||||
self.archive_type = self.ArchiveType.Zip
|
||||
self.archiver = ZipArchiver(self.path)
|
||||
else:
|
||||
if self.zipTest():
|
||||
if self.sevenZipTest():
|
||||
self.archive_type = self.ArchiveType.SevenZip
|
||||
self.archiver = SevenZipArchiver(self.path)
|
||||
|
||||
elif self.zipTest():
|
||||
self.archive_type = self.ArchiveType.Zip
|
||||
self.archiver = ZipArchiver(self.path)
|
||||
|
||||
@ -595,6 +705,9 @@ class ComicArchive:
|
||||
self.path = path
|
||||
self.archiver.path = path
|
||||
|
||||
def sevenZipTest(self):
|
||||
return py7zr.is_7zfile(self.path)
|
||||
|
||||
def zipTest(self):
|
||||
return zipfile.is_zipfile(self.path)
|
||||
|
||||
@ -604,6 +717,9 @@ class ComicArchive:
|
||||
except:
|
||||
return False
|
||||
|
||||
def isSevenZip(self):
|
||||
return self.archive_type == self.ArchiveType.SevenZip
|
||||
|
||||
def isZip(self):
|
||||
return self.archive_type == self.ArchiveType.Zip
|
||||
|
||||
@ -645,7 +761,7 @@ class ComicArchive:
|
||||
|
||||
if (
|
||||
# or self.isFolder() )
|
||||
(self.isZip() or self.isRar())
|
||||
(self.isSevenZip() or self.isZip() or self.isRar())
|
||||
and
|
||||
(self.getNumberOfPages() > 0)
|
||||
|
||||
@ -826,7 +942,7 @@ class ComicArchive:
|
||||
def hasCBI(self):
|
||||
if self.has_cbi is None:
|
||||
|
||||
# if ( not ( self.isZip() or self.isRar()) or not
|
||||
# if ( not (self.isSevenZip() or self.isZip() or self.isRar()) or not
|
||||
# self.seemsToBeAComicArchive() ):
|
||||
if not self.seemsToBeAComicArchive():
|
||||
self.has_cbi = False
|
||||
|
@ -258,7 +258,9 @@ def process_file_cli(filename, opts, settings, match_results):
|
||||
if batch_mode:
|
||||
brief = "{0}: ".format(filename)
|
||||
|
||||
if ca.isZip():
|
||||
if ca.isSevenZip():
|
||||
brief += "7Z archive "
|
||||
elif ca.isZip():
|
||||
brief += "ZIP archive "
|
||||
elif ca.isRar():
|
||||
brief += "RAR archive "
|
||||
@ -498,7 +500,9 @@ def process_file_cli(filename, opts, settings, match_results):
|
||||
|
||||
new_ext = None # default
|
||||
if settings.rename_extension_based_on_archive:
|
||||
if ca.isZip():
|
||||
if ca.isSevenZip():
|
||||
new_ext = ".cb7"
|
||||
elif ca.isZip():
|
||||
new_ext = ".cbz"
|
||||
elif ca.isRar():
|
||||
new_ext = ".cbr"
|
||||
|
@ -197,7 +197,7 @@ class FileSelectionList(QWidget):
|
||||
centerWindowOnParent(progdialog)
|
||||
#QCoreApplication.processEvents()
|
||||
#progdialog.show()
|
||||
|
||||
|
||||
QCoreApplication.processEvents()
|
||||
firstAdded = None
|
||||
self.twList.setSortingEnabled(False)
|
||||
@ -212,7 +212,7 @@ class FileSelectionList(QWidget):
|
||||
row = self.addPathItem(f)
|
||||
if firstAdded is None and row is not None:
|
||||
firstAdded = row
|
||||
|
||||
|
||||
progdialog.hide()
|
||||
QCoreApplication.processEvents()
|
||||
|
||||
@ -335,7 +335,9 @@ class FileSelectionList(QWidget):
|
||||
filename_item.setText(item_text)
|
||||
filename_item.setData(Qt.ToolTipRole, item_text)
|
||||
|
||||
if fi.ca.isZip():
|
||||
if fi.ca.isSevenZip():
|
||||
item_text = "7Z"
|
||||
elif fi.ca.isZip():
|
||||
item_text = "ZIP"
|
||||
elif fi.ca.isRar():
|
||||
item_text = "RAR"
|
||||
|
@ -67,7 +67,9 @@ class RenameWindow(QtWidgets.QDialog):
|
||||
|
||||
new_ext = None # default
|
||||
if self.settings.rename_extension_based_on_archive:
|
||||
if ca.isZip():
|
||||
if ca.isSevenZip():
|
||||
new_ext = ".cb7"
|
||||
elif ca.isZip():
|
||||
new_ext = ".cbz"
|
||||
elif ca.isRar():
|
||||
new_ext = ".cbr"
|
||||
|
@ -87,7 +87,7 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
|
||||
def __init__(self, file_list, settings, parent=None, opts=None):
|
||||
super(TaggerWindow, self).__init__(parent)
|
||||
|
||||
|
||||
uic.loadUi(ComicTaggerSettings.getUIFile('taggerwindow.ui'), self)
|
||||
self.settings = settings
|
||||
|
||||
@ -294,7 +294,7 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
|
||||
self.setWindowIcon(
|
||||
QtGui.QIcon(ComicTaggerSettings.getGraphic('app.png')))
|
||||
|
||||
|
||||
if self.comic_archive is None:
|
||||
self.setWindowTitle(self.appName)
|
||||
else:
|
||||
@ -584,7 +584,7 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
event.accept()
|
||||
|
||||
def getUrlFromLocalFileID(self, localFileID):
|
||||
return localFileID.toLocalFile()
|
||||
return localFileID.toLocalFile()
|
||||
|
||||
def dropEvent(self, event):
|
||||
# if self.dirtyFlagVerification("Open Archive",
|
||||
@ -675,7 +675,9 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
|
||||
self.lblFilename.setText(filename)
|
||||
|
||||
if ca.isZip():
|
||||
if ca.isSevenZip():
|
||||
self.lblArchiveType.setText("7Z archive")
|
||||
elif ca.isZip():
|
||||
self.lblArchiveType.setText("ZIP archive")
|
||||
elif ca.isRar():
|
||||
self.lblArchiveType.setText("RAR archive")
|
||||
@ -985,7 +987,7 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
dialog.setDirectory(self.settings.last_opened_folder)
|
||||
|
||||
if not folder_mode:
|
||||
archive_filter = "Comic archive files (*.cbz *.zip *.cbr *.rar)"
|
||||
archive_filter = "Comic archive files (*.cb7 *.7z *.cbz *.zip *.cbr *.rar)"
|
||||
filters = [
|
||||
archive_filter,
|
||||
"Any files (*)"
|
||||
@ -1164,11 +1166,11 @@ class TaggerWindow(QtWidgets.QMainWindow):
|
||||
|
||||
def updateCreditColors(self):
|
||||
#!!!ATB qt5 porting TODO
|
||||
#return
|
||||
#return
|
||||
inactive_color = QtGui.QColor(255, 170, 150)
|
||||
active_palette = self.leSeries.palette()
|
||||
active_color = active_palette.color(QtGui.QPalette.Base)
|
||||
|
||||
|
||||
inactive_brush = QtGui.QBrush(inactive_color)
|
||||
active_brush = QtGui.QBrush(active_color)
|
||||
|
||||
|
@ -3,3 +3,4 @@ configparser
|
||||
natsort >=8.1.0
|
||||
pillow>=4.3.0
|
||||
requests
|
||||
py7zr
|
||||
|
Loading…
Reference in New Issue
Block a user