Sync to trunk.

This commit is contained in:
John Schember 2009-06-06 17:59:41 -04:00
commit 7b591f3d72
11 changed files with 101 additions and 123 deletions

View File

@ -31,6 +31,7 @@ resources_dir = os.path.join(base_dir, 'Resources')
frameworks_dir = os.path.join(base_dir, 'Frameworks') frameworks_dir = os.path.join(base_dir, 'Frameworks')
base_name = os.path.splitext(name)[0] base_name = os.path.splitext(name)[0]
python = os.path.join(base_dir, 'MacOS', 'python') python = os.path.join(base_dir, 'MacOS', 'python')
qt_plugins = os.path.join(os.path.realpath(base_dir), 'MacOS')
loader_path = os.path.join(dirpath, base_name+'.py') loader_path = os.path.join(dirpath, base_name+'.py')
loader = open(loader_path, 'w') loader = open(loader_path, 'w')
site_packages = glob.glob(resources_dir+'/lib/python*/site-packages.zip')[0] site_packages = glob.glob(resources_dir+'/lib/python*/site-packages.zip')[0]
@ -46,9 +47,10 @@ print >>loader, '%(function)s()'
loader.close() loader.close()
os.chmod(loader_path, 0700) os.chmod(loader_path, 0700)
os.environ['PYTHONHOME'] = resources_dir os.environ['PYTHONHOME'] = resources_dir
os.environ['FC_CONFIG_DIR'] = os.path.join(resources_dir, 'fonts') os.environ['FONTCONFIG_PATH'] = os.path.join(resources_dir, 'fonts')
os.environ['MAGICK_HOME'] = os.path.join(frameworks_dir, 'ImageMagick') os.environ['MAGICK_HOME'] = os.path.join(frameworks_dir, 'ImageMagick')
os.environ['DYLD_LIBRARY_PATH'] = os.path.join(frameworks_dir, 'ImageMagick', 'lib') os.environ['DYLD_LIBRARY_PATH'] = os.path.join(frameworks_dir, 'ImageMagick', 'lib')
os.environ['QT_PLUGIN_PATH'] = qt_plugins
args = [path, loader_path] + sys.argv[1:] args = [path, loader_path] + sys.argv[1:]
os.execv(python, args) os.execv(python, args)
''' '''
@ -259,19 +261,11 @@ _check_symlinks_prescript()
dest = os.path.join(frameworks_dir, os.path.basename(f)) dest = os.path.join(frameworks_dir, os.path.basename(f))
if os.path.exists(dest): if os.path.exists(dest):
os.remove(dest) os.remove(dest)
os.link(f, dest) shutil.copyfile(f, dest)
dst = os.path.join(resource_dir, 'fonts') dst = os.path.join(resource_dir, 'fonts')
if os.path.exists(dst): if os.path.exists(dst):
shutil.rmtree(dst) shutil.rmtree(dst)
shutil.copytree('/usr/local/etc/fonts', dst, symlinks=False) shutil.copytree('/usr/local/etc/fonts', dst, symlinks=False)
for x in os.listdir('/usr/local/etc/fonts'):
dst = os.path.join(frameworks_dir, x)
y = os.path.join('/usr/local/etc/fonts', x)
if os.path.isdir(dst):
if os.path.exists(dst): shutil.rmtree(dst)
shutil.copytree(y, dst)
else:
os.link(y, dst)
print print
print 'Adding IPython' print 'Adding IPython'

View File

@ -59,6 +59,16 @@ if __name__ == '__main__':
'calibre_postinstall = calibre.linux:post_install') 'calibre_postinstall = calibre.linux:post_install')
optional = [] optional = []
if iswindows:
optional.append(Extension('calibre.plugins.winutil',
sources=['src/calibre/utils/windows/winutil.c'],
libraries=['shell32', 'setupapi'],
include_dirs=os.environ.get('INCLUDE',
'C:/WinDDK/6001.18001/inc/api/;'
'C:/WinDDK/6001.18001/inc/crt/').split(';'),
extra_compile_args=['/X']
))
podofo_inc = '/usr/include/podofo' if islinux else \ podofo_inc = '/usr/include/podofo' if islinux else \
'C:\\podofo\\include\\podofo' if iswindows else \ 'C:\\podofo\\include\\podofo' if iswindows else \
@ -83,6 +93,7 @@ if __name__ == '__main__':
r'C:\cygwin\home\kovid\fontconfig\lib' if iswindows else \ r'C:\cygwin\home\kovid\fontconfig\lib' if iswindows else \
'/Users/kovid/fontconfig/lib' '/Users/kovid/fontconfig/lib'
ext_modules = optional + [ ext_modules = optional + [
Extension('calibre.plugins.fontconfig', Extension('calibre.plugins.fontconfig',
@ -113,15 +124,6 @@ if __name__ == '__main__':
['src/calibre/gui2/pictureflow/pictureflow.sip'] ['src/calibre/gui2/pictureflow/pictureflow.sip']
) )
] ]
if iswindows:
ext_modules.append(Extension('calibre.plugins.winutil',
sources=['src/calibre/utils/windows/winutil.c'],
libraries=['shell32', 'setupapi'],
include_dirs=os.environ.get('INCLUDE',
'C:/WinDDK/6001.18001/inc/api/;'
'C:/WinDDK/6001.18001/inc/crt/').split(';'),
extra_compile_args=['/X']
))
if isosx: if isosx:
ext_modules.append(Extension('calibre.plugins.usbobserver', ext_modules.append(Extension('calibre.plugins.usbobserver',
sources=['src/calibre/devices/usbobserver/usbobserver.c'], sources=['src/calibre/devices/usbobserver/usbobserver.c'],

View File

@ -48,9 +48,9 @@ class CLI(object):
(self._card_b_prefix and path.startswith(self._card_b_prefix))): (self._card_b_prefix and path.startswith(self._card_b_prefix))):
path = self._main_prefix + path[1:] path = self._main_prefix + path[1:]
elif path.startswith('carda:'): elif path.startswith('carda:'):
path = path.replace('carda:', self._card_prefix[:-1]) path = path.replace('carda:', self._card_a_prefix[:-1])
elif path.startswith('cardb:'): elif path.startswith('cardb:'):
path = path.replace('cardb:', self._card_prefix[:-1]) path = path.replace('cardb:', self._card_b_prefix[:-1])
return path return path
def list(self, path, recurse=False, end_session=True, munge=True): def list(self, path, recurse=False, end_session=True, munge=True):

View File

@ -174,7 +174,8 @@ class Device(DeviceConfig, DevicePlugin):
cbsz = stats.f_frsize * stats.f_bavail cbsz = stats.f_frsize * stats.f_bavail
else: else:
msz = self._windows_space(self._main_prefix)[1] msz = self._windows_space(self._main_prefix)[1]
csz = self._windows_space(self._card_prefix)[1] casz = self._windows_space(self._card_a_prefix)[1]
cbsz = self._windows_space(self._card_b_prefix)[1]
return (msz, casz, cbsz) return (msz, casz, cbsz)
@ -422,14 +423,13 @@ class Device(DeviceConfig, DevicePlugin):
if label is None: if label is None:
label = self.STORAGE_CARD_VOLUME_LABEL + ' 2' label = self.STORAGE_CARD_VOLUME_LABEL + ' 2'
extra = 0 extra = 0
label = label.replace(' ', '_')
while True: while True:
q = '_(%d)'%extra if extra else '' q = '_(%d)'%extra if extra else ''
if not os.path.exists('/media/'+label+q): if not os.path.exists('/media/'+label+q):
break break
extra += 1 extra += 1
if extra: if extra:
label += '_(%d)'%extra label += ' (%d)'%extra
def do_mount(node, label): def do_mount(node, label):
cmd = ['pmount', '-w', '-s'] cmd = ['pmount', '-w', '-s']
@ -504,7 +504,7 @@ class Device(DeviceConfig, DevicePlugin):
def do_it(drives): def do_it(drives):
for d in drives: for d in drives:
try: try:
winutil.eject_drive(d) winutil.eject_drive(bytes(d)[0])
except: except:
pass pass

View File

@ -28,7 +28,7 @@ class EPUBInput(InputFormatPlugin):
f.write(raw[1024:]) f.write(raw[1024:])
@classmethod @classmethod
def process_ecryption(cls, encfile, opf, log): def process_encryption(cls, encfile, opf, log):
key = None key = None
m = re.search(r'(?i)(urn:uuid:[0-9a-f-]+)', open(opf, 'rb').read()) m = re.search(r'(?i)(urn:uuid:[0-9a-f-]+)', open(opf, 'rb').read())
if m: if m:

View File

@ -18,8 +18,7 @@ except:
from calibre.ebooks.metadata import MetaInformation, authors_to_string from calibre.ebooks.metadata import MetaInformation, authors_to_string
from calibre.utils.pdftk import set_metadata as pdftk_set_metadata from calibre.utils.pdftk import set_metadata as pdftk_set_metadata
from calibre.utils.podofo import get_metadata as podofo_get_metadata, \ from calibre.utils.podofo import get_metadata as podofo_get_metadata, \
set_metadata as podofo_set_metadata, Unavailable, write_first_page, \ set_metadata as podofo_set_metadata, Unavailable, get_metadata_quick
get_metadata_quick
def get_quick_metadata(stream): def get_quick_metadata(stream):
raw = stream.read() raw = stream.read()
@ -32,19 +31,18 @@ def get_quick_metadata(stream):
def get_metadata(stream, extract_cover=True): def get_metadata(stream, extract_cover=True):
try: try:
mi = podofo_get_metadata(stream) with TemporaryDirectory('_pdfmeta') as tdir:
cpath = os.path.join(tdir, 'cover.pdf')
if not extract_cover:
cpath = None
mi = podofo_get_metadata(stream, cpath=cpath)
if mi.cover is not None:
cdata = get_cover(mi.cover)
mi.cover = None
if cdata is not None:
mi.cover_data = ('jpg', cdata)
except Unavailable: except Unavailable:
mi = get_metadata_pypdf(stream) mi = get_metadata_pypdf(stream)
stream.seek(0)
if extract_cover and _imagemagick_loaded:
try:
cdata = get_cover(stream)
if cdata is not None:
mi.cover_data = ('jpg', cdata)
except:
import traceback
traceback.print_exc()
return mi return mi
@ -127,17 +125,13 @@ def set_metadata_pypdf(stream, mi):
stream.write(out_str.read()) stream.write(out_str.read())
stream.seek(0) stream.seek(0)
def get_cover(stream): def get_cover(cover_path):
stream.seek(0) with ImageMagick():
with TemporaryDirectory('_pdfmeta') as tdir: wand = NewMagickWand()
cover_path = os.path.join(tdir, 'cover.pdf') MagickReadImage(wand, cover_path)
write_first_page(stream, cover_path) MagickSetImageFormat(wand, 'JPEG')
with ImageMagick(): MagickWriteImage(wand, '%s.jpg' % cover_path)
wand = NewMagickWand() return open('%s.jpg' % cover_path, 'rb').read()
MagickReadImage(wand, cover_path)
MagickSetImageFormat(wand, 'JPEG')
MagickWriteImage(wand, '%s.jpg' % cover_path)
return open('%s.jpg' % cover_path, 'rb').read()

View File

@ -108,6 +108,11 @@ class Worker(object):
self._env['PYTHONHOME'] = resources self._env['PYTHONHOME'] = resources
self._env['MAGICK_HOME'] = os.path.join(fd, 'ImageMagick') self._env['MAGICK_HOME'] = os.path.join(fd, 'ImageMagick')
self._env['DYLD_LIBRARY_PATH'] = os.path.join(fd, 'ImageMagick', 'lib') self._env['DYLD_LIBRARY_PATH'] = os.path.join(fd, 'ImageMagick', 'lib')
self._env['FONTCONFIG_PATH'] = \
os.path.join(os.path.realpath(resources), 'fonts')
self._env['QT_PLUGIN_PATH'] = \
os.path.join(self.osx_contents_dir, 'MacOS')
if isfrozen and not (iswindows or isosx): if isfrozen and not (iswindows or isosx):
self._env['LD_LIBRARY_PATH'] = getattr(sys, 'frozen_path') + ':'\ self._env['LD_LIBRARY_PATH'] = getattr(sys, 'frozen_path') + ':'\
+ os.environ.get('LD_LIBRARY_PATH', '') + os.environ.get('LD_LIBRARY_PATH', '')

View File

@ -39,9 +39,6 @@ PARALLEL_FUNCS = {
'write_pdf_metadata' : 'write_pdf_metadata' :
('calibre.utils.podofo.__init__', 'set_metadata_', None), ('calibre.utils.podofo.__init__', 'set_metadata_', None),
'write_pdf_first_page' :
('calibre.utils.podofo.__init__', 'write_first_page_', None),
'save_book' : 'save_book' :
('calibre.ebooks.metadata.worker', 'save_book', 'notification'), ('calibre.ebooks.metadata.worker', 'save_book', 'notification'),
} }

View File

@ -19,39 +19,7 @@ podofo, podofo_err = plugins['podofo']
class Unavailable(Exception): pass class Unavailable(Exception): pass
def write_first_page(stream, opath): def get_metadata(stream, cpath=None):
if not podofo:
raise Unavailable(podofo_err)
pt = PersistentTemporaryFile('_podofo.pdf')
pt.write(stream.read())
pt.close()
server = Server(pool_size=1)
job = ParallelJob('write_pdf_first_page', 'Extract first page of pdf',
lambda x,y:x, args=[pt.name, opath])
server.add_job(job)
while not job.is_finished:
time.sleep(0.1)
job.update()
job.update()
server.close()
if not job.result:
raise ValueError('Failed to extract first page: ' + job.details)
def write_first_page_(inpath, outpath):
p = podofo.PDFDoc()
p.open(inpath)
pages = p.pages
if pages < 1:
raise ValueError('PDF has no pages')
if pages == 1:
shutil.copyfile(inpath, outpath)
return True
p.delete_pages(1, pages-1)
p.save(outpath)
return True
def get_metadata(stream):
if not podofo: if not podofo:
raise Unavailable(podofo_err) raise Unavailable(podofo_err)
pt = PersistentTemporaryFile('_podofo.pdf') pt = PersistentTemporaryFile('_podofo.pdf')
@ -59,7 +27,7 @@ def get_metadata(stream):
pt.close() pt.close()
server = Server(pool_size=1) server = Server(pool_size=1)
job = ParallelJob('read_pdf_metadata', 'Read pdf metadata', job = ParallelJob('read_pdf_metadata', 'Read pdf metadata',
lambda x,y:x, args=[pt.name]) lambda x,y:x, args=[pt.name, cpath])
server.add_job(job) server.add_job(job)
while not job.is_finished: while not job.is_finished:
time.sleep(0.1) time.sleep(0.1)
@ -69,7 +37,10 @@ def get_metadata(stream):
server.close() server.close()
if job.result is None: if job.result is None:
raise ValueError('Failed to read metadata: ' + job.details) raise ValueError('Failed to read metadata: ' + job.details)
title, authors, creator = job.result title, authors, creator, ok = job.result
if not ok:
print 'Failed to extract cover:'
print job.details
if title == '_': if title == '_':
title = getattr(stream, 'name', _('Unknown')) title = getattr(stream, 'name', _('Unknown'))
title = os.path.splitext(title)[0] title = os.path.splitext(title)[0]
@ -78,6 +49,8 @@ def get_metadata(stream):
if creator: if creator:
mi.book_producer = creator mi.book_producer = creator
if os.path.exists(pt.name): os.remove(pt.name) if os.path.exists(pt.name): os.remove(pt.name)
if ok:
mi.cover = cpath
return mi return mi
def get_metadata_quick(raw): def get_metadata_quick(raw):
@ -94,8 +67,7 @@ def get_metadata_quick(raw):
mi.book_producer = creator mi.book_producer = creator
return mi return mi
def get_metadata_(path, cpath=None):
def get_metadata_(path):
p = podofo.PDFDoc() p = podofo.PDFDoc()
p.open(path) p.open(path)
title = p.title title = p.title
@ -104,7 +76,23 @@ def get_metadata_(path):
author = p.author author = p.author
authors = string_to_authors(author) if author else [_('Unknown')] authors = string_to_authors(author) if author else [_('Unknown')]
creator = p.creator creator = p.creator
return (title, authors, creator) ok = True
try:
if cpath is not None:
pages = p.pages
if pages < 1:
raise ValueError('PDF has no pages')
if True or pages == 1:
shutil.copyfile(path, cpath)
else:
p.extract_first_page()
p.save(cpath)
except:
import traceback
traceback.print_exc()
ok = False
return (title, authors, creator, ok)
def prep(val): def prep(val):
if not val: if not val:

View File

@ -143,18 +143,15 @@ podofo_PDFDoc_version_getter(podofo_PDFDoc *self, void *closure) {
static PyObject * static PyObject *
podofo_PDFDoc_delete_pages(podofo_PDFDoc *self, PyObject *args, PyObject *kwargs) { podofo_PDFDoc_extract_first_page(podofo_PDFDoc *self, PyObject *args, PyObject *kwargs) {
int first_page, num_pages; int i, num_pages;
if (PyArg_ParseTuple(args, "ii", &first_page, &num_pages)) { try {
try { while (self->doc->GetPageCount() > 1) self->doc->GetPagesTree()->DeletePage(1);
self->doc->DeletePages(first_page, num_pages); } catch(const PdfError & err) {
} catch(const PdfError & err) { podofo_set_exception(err);
podofo_set_exception(err); return NULL;
return NULL; }
} Py_RETURN_NONE;
} else return NULL;
Py_INCREF(Py_None);
return Py_None;
} }
static PyObject * static PyObject *
@ -313,8 +310,8 @@ static PyMethodDef podofo_PDFDoc_methods[] = {
{"save", (PyCFunction)podofo_PDFDoc_save, METH_VARARGS, {"save", (PyCFunction)podofo_PDFDoc_save, METH_VARARGS,
"Save the PDF document to a path on disk" "Save the PDF document to a path on disk"
}, },
{"delete_pages", (PyCFunction)podofo_PDFDoc_delete_pages, METH_VARARGS, {"extract_first_page", (PyCFunction)podofo_PDFDoc_extract_first_page, METH_VARARGS,
"delete_pages(start_page, num_pages) -> int, int\nDelete pages from the PDF document." "extract_first_page() -> Remove all but the first page."
}, },
{NULL} /* Sentinel */ {NULL} /* Sentinel */

View File

@ -308,7 +308,7 @@ get_all_removable_disks(struct tagDrives *g_drives)
static DEVINST static DEVINST
GetDrivesDevInstByDeviceNumber(long DeviceNumber, GetDrivesDevInstByDeviceNumber(long DeviceNumber,
UINT DriveType, char* szDosDeviceName) UINT DriveType, LPWSTR szDosDeviceName)
{ {
GUID *guid; GUID *guid;
HDEVINFO hDevInfo; HDEVINFO hDevInfo;
@ -319,8 +319,12 @@ GetDrivesDevInstByDeviceNumber(long DeviceNumber,
long res; long res;
HANDLE hDrive; HANDLE hDrive;
STORAGE_DEVICE_NUMBER sdn; STORAGE_DEVICE_NUMBER sdn;
SP_DEVICE_INTERFACE_DATA spdid;
SP_DEVINFO_DATA spdd;
DWORD dwSize;
IsFloppy = (strstr(szDosDeviceName, "\\Floppy") != NULL); // is there a better way?
IsFloppy = (wcsstr(szDosDeviceName, L"\\Floppy") != NULL); // is there a better way?
switch (DriveType) { switch (DriveType) {
case DRIVE_REMOVABLE: case DRIVE_REMOVABLE:
@ -357,12 +361,7 @@ GetDrivesDevInstByDeviceNumber(long DeviceNumber,
bRet = FALSE; bRet = FALSE;
pspdidd = pspdidd = (PSP_DEVICE_INTERFACE_DETAIL_DATA)Buf;
(PSP_DEVICE_INTERFACE_DETAIL_DATA)Buf;
SP_DEVICE_INTERFACE_DATA spdid;
SP_DEVINFO_DATA spdd;
DWORD dwSize;
spdid.cbSize = sizeof(spdid); spdid.cbSize = sizeof(spdid);
while ( TRUE ) { while ( TRUE ) {
@ -420,8 +419,11 @@ GetDrivesDevInstByDeviceNumber(long DeviceNumber,
static BOOL static BOOL
eject_drive_letter(char DriveLetter) { eject_drive_letter(WCHAR DriveLetter) {
char szRootPath[4], szDevicePath[3], szVolumeAccessPath[7], szDosDeviceName[MAX_PATH]; LPWSTR szRootPath = L"X:\\",
szDevicePath = L"X:",
szVolumeAccessPath = L"\\\\.\\X:";
WCHAR szDosDeviceName[MAX_PATH];
long DeviceNumber, res, tries; long DeviceNumber, res, tries;
HANDLE hVolume; HANDLE hVolume;
STORAGE_DEVICE_NUMBER sdn; STORAGE_DEVICE_NUMBER sdn;
@ -429,17 +431,15 @@ eject_drive_letter(char DriveLetter) {
DEVINST DevInst; DEVINST DevInst;
ULONG Status; ULONG Status;
ULONG ProblemNumber; ULONG ProblemNumber;
UINT DriveType;
PNP_VETO_TYPE VetoType; PNP_VETO_TYPE VetoType;
WCHAR VetoNameW[MAX_PATH]; WCHAR VetoNameW[MAX_PATH];
BOOL bSuccess; BOOL bSuccess;
DEVINST DevInstParent; DEVINST DevInstParent;
szRootPath[0] = DriveLetter; szRootPath[1] = ':'; szRootPath[2] = '\\'; szRootPath[3] = (char)0; szRootPath[0] = DriveLetter;
szDevicePath[0] = DriveLetter; szDevicePath[1] = ':'; szDevicePath[2] = (char)0; szDevicePath[0] = DriveLetter;
szVolumeAccessPath[0] = '\\'; szVolumeAccessPath[1] = '\\'; szVolumeAccessPath[2] = '.'; szVolumeAccessPath[4] = DriveLetter;
szVolumeAccessPath[3] = '\\'; szVolumeAccessPath[4] = DriveLetter; szVolumeAccessPath[5] = ':';
szVolumeAccessPath[6] = (char)0;
DeviceNumber = -1; DeviceNumber = -1;
@ -472,6 +472,8 @@ eject_drive_letter(char DriveLetter) {
return FALSE; return FALSE;
} }
DriveType = GetDriveType(szRootPath);
DevInst = GetDrivesDevInstByDeviceNumber(DeviceNumber, DevInst = GetDrivesDevInstByDeviceNumber(DeviceNumber,
DriveType, szDosDeviceName); DriveType, szDosDeviceName);
if (DevInst == 0) return FALSE; if (DevInst == 0) return FALSE;
@ -479,7 +481,6 @@ eject_drive_letter(char DriveLetter) {
DevInstParent = 0; DevInstParent = 0;
Status = 0; Status = 0;
ProblemNumber = 0; ProblemNumber = 0;
PNP_VETO_TYPE VetoType;
bSuccess = FALSE; bSuccess = FALSE;
res = CM_Get_Parent(&DevInstParent, DevInst, 0); res = CM_Get_Parent(&DevInstParent, DevInst, 0);
@ -508,7 +509,7 @@ winutil_eject_drive(PyObject *self, PyObject *args) {
if (!PyArg_ParseTuple(args, "c", &DriveLetter)) return NULL; if (!PyArg_ParseTuple(args, "c", &DriveLetter)) return NULL;
if (!eject_drive_letter(DriveLetter)) return NULL; if (!eject_drive_letter((WCHAR)DriveLetter)) return NULL;
Py_RETURN_NONE; Py_RETURN_NONE;
} }