fix p7zip-rar error and files with ' or " by using arg lists instead of strings (#633)

* Revert "Revert "fix files with ' or " by using arg lists instead of strings (#581)" (#628)"

This reverts commit b528dab711.

* handle FileNotFoundError

* modify unar handling

* remove unneeded utf-8 encoding

* dont uft-8 encode 7z

* remove utf-8 encoding from 7z calls

* don't extract stderr

* add extraction error

* edit error message

* remove debug

* remove kindlegen location from GUI

* remove comment
This commit is contained in:
Alex Xu
2023-12-21 12:52:35 -08:00
committed by GitHub
parent 6cdd9d5909
commit 3988f2012f
3 changed files with 39 additions and 54 deletions
+21 -28
View File
@@ -22,12 +22,13 @@ import os
import platform
import subprocess
import distro
from psutil import Popen
from shutil import move
from subprocess import STDOUT, PIPE
from xml.dom.minidom import parseString
from xml.parsers.expat import ExpatError
EXTRACTION_ERROR = 'Failed to extract archive. Try extracting file outside of KCC.'
class ComicArchive:
def __init__(self, filepath):
@@ -35,41 +36,35 @@ class ComicArchive:
self.type = None
if not os.path.isfile(self.filepath):
raise OSError('File not found.')
process = Popen('7z l -y -p1 "' + self.filepath + '"', stderr=STDOUT, stdout=PIPE, stdin=PIPE, shell=True)
for line in process.stdout:
process = subprocess.run(['7z', 'l', '-y', '-p1', self.filepath], stderr=STDOUT, stdout=PIPE)
for line in process.stdout.splitlines():
if b'Type =' in line:
self.type = line.rstrip().decode().split(' = ')[1].upper()
break
process.communicate()
if process.returncode != 0 and distro.id() == 'fedora':
process = Popen('unrar l -y -p1 "' + self.filepath + '"', stderr=STDOUT, stdout=PIPE, stdin=PIPE, shell=True)
for line in process.stdout:
process = subprocess.run(['unrar', 'l', '-y', '-p1', self.filepath], stderr=STDOUT, stdout=PIPE)
for line in process.stdout.splitlines():
if b'Details: ' in line:
self.type = line.rstrip().decode().split(' ')[1].upper()
break
process.communicate()
if process.returncode != 0:
raise OSError(process.stdout.strip())
raise OSError(EXTRACTION_ERROR)
def extract(self, targetdir):
if not os.path.isdir(targetdir):
raise OSError('Target directory doesn\'t exist.')
process = Popen('7z x -y -xr!__MACOSX -xr!.DS_Store -xr!thumbs.db -xr!Thumbs.db -o"' + targetdir + '" "' +
self.filepath + '"', stdout=PIPE, stderr=STDOUT, stdin=PIPE, shell=True)
process.communicate()
process = subprocess.run(['7z', 'x', '-y', '-xr!__MACOSX', '-xr!.DS_Store', '-xr!thumbs.db', '-xr!Thumbs.db', '-o' + targetdir, self.filepath],
stdout=PIPE, stderr=STDOUT)
if process.returncode != 0 and distro.id() == 'fedora':
process = Popen('unrar x -y -x__MACOSX -x.DS_Store -xthumbs.db -xThumbs.db "' + self.filepath + '" "' +
targetdir + '"', stdout=PIPE, stderr=STDOUT, stdin=PIPE, shell=True)
process.communicate()
process = subprocess.run(['unrar', 'x', '-y', '-x__MACOSX', '-x.DS_Store', '-xthumbs.db', '-xThumbs.db', self.filepath, targetdir]
, stdout=PIPE, stderr=STDOUT)
if process.returncode != 0:
raise OSError('Failed to extract archive.')
raise OSError(EXTRACTION_ERROR)
elif process.returncode != 0 and platform.system() == 'Darwin':
process = subprocess.run(f"unar '{self.filepath}' -f -o '{targetdir}'",
stdout=PIPE, stderr=STDOUT, stdin=PIPE, shell=True)
if process.returncode != 0:
raise Exception(process.stdout.decode("utf-8"))
process = subprocess.run(['unar', self.filepath, '-f', '-o', targetdir],
stdout=PIPE, stderr=STDOUT)
elif process.returncode != 0:
raise OSError('Failed to extract archive. Check if p7zip-rar is installed.')
raise OSError(EXTRACTION_ERROR)
tdir = os.listdir(targetdir)
if 'ComicInfo.xml' in tdir:
tdir.remove('ComicInfo.xml')
@@ -78,19 +73,17 @@ class ComicArchive:
def addFile(self, sourcefile):
if self.type in ['RAR', 'RAR5']:
raise NotImplementedError
process = Popen('7z a -y "' + self.filepath + '" "' + sourcefile + '"',
stdout=PIPE, stderr=STDOUT, stdin=PIPE, shell=True)
process.communicate()
process = subprocess.run(['7z', 'a', '-y', self.filepath, sourcefile],
stdout=PIPE, stderr=STDOUT)
if process.returncode != 0:
raise OSError('Failed to add the file.')
def extractMetadata(self):
process = Popen('7z x -y -so "' + self.filepath + '" ComicInfo.xml',
stdout=PIPE, stderr=STDOUT, stdin=PIPE, shell=True)
xml = process.communicate()
process = subprocess.run(['7z', 'x', '-y', '-so', self.filepath, 'ComicInfo.xml'],
stdout=PIPE, stderr=STDOUT)
if process.returncode != 0:
raise OSError('Failed to extract archive.')
raise OSError(EXTRACTION_ERROR)
try:
return parseString(xml[0])
return parseString(process.stdout)
except ExpatError:
return None