about summary refs log tree commit diff
path: root/kindlecomicconverter/comicarchive.py
diff options
context:
space:
mode:
authorPaweł Jastrzębski <pawelj@iosphe.re>2018-07-10 08:09:04 +0200
committerPaweł Jastrzębski <pawelj@iosphe.re>2018-07-10 08:09:04 +0200
commit7904662f25997ba1466c9f21c564f1f3f066fb9f (patch)
tree7b8ffec37720bde09c90ca932a4d8b2bc5879e75 /kindlecomicconverter/comicarchive.py
parentBump MAX_IMAGE_PIXELS (close #273) (diff)
downloadkcc-7904662f25997ba1466c9f21c564f1f3f066fb9f.tar.gz
kcc-7904662f25997ba1466c9f21c564f1f3f066fb9f.tar.bz2
kcc-7904662f25997ba1466c9f21c564f1f3f066fb9f.zip
Let 7-Zip handle all archive operations
Diffstat (limited to 'kindlecomicconverter/comicarchive.py')
-rw-r--r--kindlecomicconverter/comicarchive.py81
1 files changed, 81 insertions, 0 deletions
diff --git a/kindlecomicconverter/comicarchive.py b/kindlecomicconverter/comicarchive.py
new file mode 100644
index 0000000..df9029c
--- /dev/null
+++ b/kindlecomicconverter/comicarchive.py
@@ -0,0 +1,81 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
+# Copyright (c) 2013-2018 Pawel Jastrzebski <pawelj@iosphe.re>
+#
+# Permission to use, copy, modify, and/or distribute this software for
+# any purpose with or without fee is hereby granted, provided that the
+# above copyright notice and this permission notice appear in all
+# copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
+# OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+#
+
+import os
+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
+
+
+class ComicArchive:
+    def __init__(self, filepath):
+        self.filepath = filepath
+        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, shell=True)
+        for line in process.stdout:
+            if b'Type =' in line:
+                self.type = line.rstrip().decode().split(' = ')[1].upper()
+                break
+        process.communicate()
+        if process.returncode != 0:
+            raise OSError('Archive is corrupted or encrypted.')
+        elif self.type not in ['7Z', 'RAR', 'ZIP']:
+            raise OSError('Unsupported archive format.')
+
+    def extract(self, targetdir):
+        if not os.path.isdir(targetdir):
+            raise OSError('Target directory don\'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, shell=True)
+        process.communicate()
+        if process.returncode != 0:
+            raise OSError('Failed to extract archive.')
+        tdir = os.listdir(targetdir)
+        if 'ComicInfo.xml' in tdir:
+            tdir.remove('ComicInfo.xml')
+        if len(tdir) == 1 and os.path.isdir(os.path.join(targetdir, tdir[0])):
+            for f in os.listdir(os.path.join(targetdir, tdir[0])):
+                move(os.path.join(targetdir, tdir[0], f), targetdir)
+            os.rmdir(os.path.join(targetdir, tdir[0]))
+        return targetdir
+
+    def addFile(self, sourcefile):
+        if self.type == 'RAR':
+            raise NotImplementedError
+        process = Popen('7z a -y "' + self.filepath + '" "' + sourcefile + '"',
+                        stdout=PIPE, stderr=STDOUT, shell=True)
+        process.communicate()
+        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, shell=True)
+        xml = process.communicate()
+        if process.returncode != 0:
+            raise OSError('Failed to extract archive.')
+        try:
+            return parseString(xml[0])
+        except ExpatError:
+            return None