mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 10:14:46 -04:00
Merge branch 'py3' of https://github.com/eli-schwartz/calibre
This commit is contained in:
commit
dd328bdb8c
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2010, Li Fanxi <lifanxi@freemindworld.com>'
|
__copyright__ = '2010, Li Fanxi <lifanxi@freemindworld.com>'
|
||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
@ -8,7 +8,7 @@ __docformat__ = 'restructuredtext en'
|
|||||||
import sys, struct, zlib, bz2, os
|
import sys, struct, zlib, bz2, os
|
||||||
|
|
||||||
from calibre import guess_type
|
from calibre import guess_type
|
||||||
from polyglot.builtins import unicode_type, cmp
|
from polyglot.builtins import unicode_type
|
||||||
|
|
||||||
|
|
||||||
class FileStream:
|
class FileStream:
|
||||||
@ -17,17 +17,13 @@ class FileStream:
|
|||||||
return self.attr & 0x41000000 != 0x41000000
|
return self.attr & 0x41000000 != 0x41000000
|
||||||
|
|
||||||
|
|
||||||
def compareFileStream(file1, file2):
|
|
||||||
return cmp(file1.fileName, file2.fileName)
|
|
||||||
|
|
||||||
|
|
||||||
class BlockData:
|
class BlockData:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class SNBFile:
|
class SNBFile:
|
||||||
|
|
||||||
MAGIC = 'SNBP000B'
|
MAGIC = b'SNBP000B'
|
||||||
REV80 = 0x00008000
|
REV80 = 0x00008000
|
||||||
REVA3 = 0x00A3A3A3
|
REVA3 = 0x00A3A3A3
|
||||||
REVZ1 = 0x00000000
|
REVZ1 = 0x00000000
|
||||||
@ -79,7 +75,7 @@ class SNBFile:
|
|||||||
if f.attr & 0x41000000 == 0x41000000:
|
if f.attr & 0x41000000 == 0x41000000:
|
||||||
# Compressed Files
|
# Compressed Files
|
||||||
if uncompressedData is None:
|
if uncompressedData is None:
|
||||||
uncompressedData = ""
|
uncompressedData = b""
|
||||||
for i in range(self.plainBlock):
|
for i in range(self.plainBlock):
|
||||||
bzdc = bz2.BZ2Decompressor()
|
bzdc = bz2.BZ2Decompressor()
|
||||||
if (i < self.plainBlock - 1):
|
if (i < self.plainBlock - 1):
|
||||||
@ -93,8 +89,9 @@ class SNBFile:
|
|||||||
uncompressedData += bzdc.decompress(data)
|
uncompressedData += bzdc.decompress(data)
|
||||||
else:
|
else:
|
||||||
uncompressedData += data
|
uncompressedData += data
|
||||||
except Exception as e:
|
except Exception:
|
||||||
print(e)
|
import traceback
|
||||||
|
print(traceback.print_exc())
|
||||||
if len(uncompressedData) != self.plainStreamSizeUncompressed:
|
if len(uncompressedData) != self.plainStreamSizeUncompressed:
|
||||||
raise Exception()
|
raise Exception()
|
||||||
f.fileBody = uncompressedData[plainPos:plainPos+f.fileSize]
|
f.fileBody = uncompressedData[plainPos:plainPos+f.fileSize]
|
||||||
@ -105,11 +102,10 @@ class SNBFile:
|
|||||||
f.fileBody = snbFile.read(f.fileSize)
|
f.fileBody = snbFile.read(f.fileSize)
|
||||||
binPos += f.fileSize
|
binPos += f.fileSize
|
||||||
else:
|
else:
|
||||||
print(f.attr, f.fileName)
|
raise ValueError("Invalid file: {} {}".format(f.attr, f.fileName))
|
||||||
raise Exception("Invalid file")
|
|
||||||
|
|
||||||
def ParseFile(self, vfat, fileCount):
|
def ParseFile(self, vfat, fileCount):
|
||||||
fileNames = vfat[fileCount*12:].split('\0')
|
fileNames = vfat[fileCount*12:].split(b'\0')
|
||||||
for i in range(fileCount):
|
for i in range(fileCount):
|
||||||
f = FileStream()
|
f = FileStream()
|
||||||
(f.attr, f.fileNameOffset, f.fileSize) = struct.unpack('>iii', vfat[i * 12 : (i+1)*12])
|
(f.attr, f.fileNameOffset, f.fileSize) = struct.unpack('>iii', vfat[i * 12 : (i+1)*12])
|
||||||
@ -117,8 +113,8 @@ class SNBFile:
|
|||||||
self.files.append(f)
|
self.files.append(f)
|
||||||
|
|
||||||
def ParseTail(self, vtail, fileCount):
|
def ParseTail(self, vtail, fileCount):
|
||||||
self.binBlock = (self.binStreamSize + 0x8000 - 1) / 0x8000
|
self.binBlock = (self.binStreamSize + 0x8000 - 1) // 0x8000
|
||||||
self.plainBlock = (self.plainStreamSizeUncompressed + 0x8000 - 1) / 0x8000
|
self.plainBlock = (self.plainStreamSizeUncompressed + 0x8000 - 1) // 0x8000
|
||||||
for i in range(self.binBlock + self.plainBlock):
|
for i in range(self.binBlock + self.plainBlock):
|
||||||
block = BlockData()
|
block = BlockData()
|
||||||
(block.Offset,) = struct.unpack('>i', vtail[i * 4 : (i+1) * 4])
|
(block.Offset,) = struct.unpack('>i', vtail[i * 4 : (i+1) * 4])
|
||||||
@ -200,20 +196,20 @@ class SNBFile:
|
|||||||
|
|
||||||
# Sort the files in file buffer,
|
# Sort the files in file buffer,
|
||||||
# requried by the SNB file format
|
# requried by the SNB file format
|
||||||
self.files.sort(compareFileStream)
|
self.files.sort(key=lambda x: x.fileName)
|
||||||
|
|
||||||
outputFile = open(outputFile, 'wb')
|
outputFile = open(outputFile, 'wb')
|
||||||
# File header part 1
|
# File header part 1
|
||||||
vmbrp1 = struct.pack('>8siiii', SNBFile.MAGIC, SNBFile.REV80, SNBFile.REVA3, SNBFile.REVZ1, len(self.files))
|
vmbrp1 = struct.pack('>8siiii', SNBFile.MAGIC, SNBFile.REV80, SNBFile.REVA3, SNBFile.REVZ1, len(self.files))
|
||||||
|
|
||||||
# Create VFAT & file stream
|
# Create VFAT & file stream
|
||||||
vfat = ''
|
vfat = b''
|
||||||
fileNameTable = ''
|
fileNameTable = b''
|
||||||
plainStream = ''
|
plainStream = b''
|
||||||
binStream = ''
|
binStream = b''
|
||||||
for f in self.files:
|
for f in self.files:
|
||||||
vfat += struct.pack('>iii', f.attr, len(fileNameTable), f.fileSize)
|
vfat += struct.pack('>iii', f.attr, len(fileNameTable), f.fileSize)
|
||||||
fileNameTable += (f.fileName + '\0')
|
fileNameTable += (f.fileName + b'\0')
|
||||||
|
|
||||||
if f.attr & 0x41000000 == 0x41000000:
|
if f.attr & 0x41000000 == 0x41000000:
|
||||||
# Plain Files
|
# Plain Files
|
||||||
@ -224,8 +220,7 @@ class SNBFile:
|
|||||||
f.contentOffset = len(binStream)
|
f.contentOffset = len(binStream)
|
||||||
binStream += f.fileBody
|
binStream += f.fileBody
|
||||||
else:
|
else:
|
||||||
print(f.attr, f.fileName)
|
raise Exception("Unknown file type: {} {}".format(f.attr, f.fileName))
|
||||||
raise Exception("Unknown file type")
|
|
||||||
vfatCompressed = zlib.compress(vfat+fileNameTable)
|
vfatCompressed = zlib.compress(vfat+fileNameTable)
|
||||||
|
|
||||||
# File header part 2
|
# File header part 2
|
||||||
@ -239,22 +234,22 @@ class SNBFile:
|
|||||||
binBlockOffset = 0x2C + len(vfatCompressed)
|
binBlockOffset = 0x2C + len(vfatCompressed)
|
||||||
plainBlockOffset = binBlockOffset + len(binStream)
|
plainBlockOffset = binBlockOffset + len(binStream)
|
||||||
|
|
||||||
binBlock = (len(binStream) + 0x8000 - 1) / 0x8000
|
binBlock = (len(binStream) + 0x8000 - 1) // 0x8000
|
||||||
# plainBlock = (len(plainStream) + 0x8000 - 1) / 0x8000
|
# plainBlock = (len(plainStream) + 0x8000 - 1) // 0x8000
|
||||||
|
|
||||||
offset = 0
|
offset = 0
|
||||||
tailBlock = ''
|
tailBlock = b''
|
||||||
for i in range(binBlock):
|
for i in range(binBlock):
|
||||||
tailBlock += struct.pack('>i', binBlockOffset + offset)
|
tailBlock += struct.pack('>i', binBlockOffset + offset)
|
||||||
offset += 0x8000
|
offset += 0x8000
|
||||||
tailRec = ''
|
tailRec = b''
|
||||||
for f in self.files:
|
for f in self.files:
|
||||||
t = 0
|
t = 0
|
||||||
if f.IsBinary():
|
if f.IsBinary():
|
||||||
t = 0
|
t = 0
|
||||||
else:
|
else:
|
||||||
t = binBlock
|
t = binBlock
|
||||||
tailRec += struct.pack('>ii', f.contentOffset / 0x8000 + t, f.contentOffset % 0x8000)
|
tailRec += struct.pack('>ii', f.contentOffset // 0x8000 + t, f.contentOffset % 0x8000)
|
||||||
|
|
||||||
# Write binary stream
|
# Write binary stream
|
||||||
outputFile.write(binStream)
|
outputFile.write(binStream)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user