mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-31 14:33:54 -04:00
Sync to trunk.
This commit is contained in:
commit
7b591f3d72
@ -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'
|
||||||
|
20
setup.py
20
setup.py
@ -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'],
|
||||||
|
@ -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):
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
@ -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()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -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', '')
|
||||||
|
@ -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'),
|
||||||
}
|
}
|
||||||
|
@ -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:
|
||||||
|
@ -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 */
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user