From 68f24cacedae01d61133f56dcafd60e235315f0a Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 8 Dec 2008 11:37:32 -0800 Subject: [PATCH 1/4] Fix downloaded news in EPUB format causing reader resets --- src/calibre/web/feeds/__init__.py | 12 ++++ src/calibre/web/feeds/news.py | 6 +- src/calibre/web/feeds/recipes/__init__.py | 2 +- src/calibre/web/feeds/recipes/harpers_full.py | 61 +++++++++++++++++++ src/calibre/web/feeds/templates.py | 4 +- 5 files changed, 79 insertions(+), 6 deletions(-) create mode 100644 src/calibre/web/feeds/recipes/harpers_full.py diff --git a/src/calibre/web/feeds/__init__.py b/src/calibre/web/feeds/__init__.py index dffb9f8c56..7e1dee577d 100644 --- a/src/calibre/web/feeds/__init__.py +++ b/src/calibre/web/feeds/__init__.py @@ -9,6 +9,7 @@ import time, logging, traceback, copy from datetime import datetime from calibre.web.feeds.feedparser import parse +from lxml import html class Article(object): @@ -19,6 +20,17 @@ class Article(object): self.id = id self.title = title.strip() if title else title self.url = url + if summary and not isinstance(summary, unicode): + summary = summary.decode('utf-8', 'replace') + if summary and '<' in summary: + try: + s = html.fragment_fromstring(summary, create_parent=True) + summary = html.tostring(s, method='text', encoding=unicode) + except: + print 'Failed to process article summary, deleting:' + print summary.encode('utf-8') + traceback.print_exc() + summary = u'' self.summary = summary self.content = content self.date = published diff --git a/src/calibre/web/feeds/news.py b/src/calibre/web/feeds/news.py index ed94ec8270..1bc1fc77d8 100644 --- a/src/calibre/web/feeds/news.py +++ b/src/calibre/web/feeds/news.py @@ -586,9 +586,9 @@ class BasicNewsRecipe(object, LoggingInterface): if npos < 0: npos = pos ans = src[:npos+1] - if isinstance(ans, unicode): - return ans - return ans+u'\u2026' if isinstance(ans, unicode) else ans + '...' + if len(ans) < len(src): + return ans+u'\u2026' if isinstance(ans, unicode) else ans + '...' + return ans diff --git a/src/calibre/web/feeds/recipes/__init__.py b/src/calibre/web/feeds/recipes/__init__.py index 3eabaf532a..6c3c25370f 100644 --- a/src/calibre/web/feeds/recipes/__init__.py +++ b/src/calibre/web/feeds/recipes/__init__.py @@ -17,7 +17,7 @@ recipe_modules = [ 'blic', 'novosti', 'danas', 'vreme', 'times_online', 'the_scotsman', 'nytimes_sub', 'security_watch', 'cyberpresse', 'st_petersburg_times', 'clarin', 'financial_times', 'heise', 'le_monde', 'harpers', 'science_aas', - 'science_news', 'the_nation', 'lrb' + 'science_news', 'the_nation', 'lrb', 'harpers_full' ] import re, imp, inspect, time, os diff --git a/src/calibre/web/feeds/recipes/harpers_full.py b/src/calibre/web/feeds/recipes/harpers_full.py new file mode 100644 index 0000000000..c87faf195a --- /dev/null +++ b/src/calibre/web/feeds/recipes/harpers_full.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python + +__license__ = 'GPL v3' +__copyright__ = '2008, Darko Miletic ' +''' +harpers.org - paid subscription/ printed issue articles +This recipe only get's article's published in text format +images and pdf's are ignored +''' + +from calibre import strftime +from calibre.web.feeds.news import BasicNewsRecipe + +class Harpers_full(BasicNewsRecipe): + title = u"Harper's Magazine - articles from printed edition" + __author__ = u'Darko Miletic' + description = u"Harper's Magazine: Founded June 1850." + oldest_article = 30 + max_articles_per_feed = 100 + no_stylesheets = True + use_embedded_content = False + simultaneous_downloads = 1 + delay = 1 + needs_subscription = True + INDEX = strftime('http://www.harpers.org/archive/%Y/%m') + LOGIN = 'http://www.harpers.org' + cover_url = strftime('http://www.harpers.org/media/pages/%Y/%m/gif/0001.gif') + + keep_only_tags = [ dict(name='div', attrs={'id':'cached'}) ] + remove_tags = [ + dict(name='table', attrs={'class':'rcnt'}) + ,dict(name='table', attrs={'class':'rcnt topline'}) + ] + + def get_browser(self): + br = BasicNewsRecipe.get_browser() + if self.username is not None and self.password is not None: + br.open(self.LOGIN) + br.select_form(nr=1) + br['handle' ] = self.username + br['password'] = self.password + br.submit() + return br + + def parse_index(self): + articles = [] + print 'Processing ' + self.INDEX + soup = self.index_to_soup(self.INDEX) + for item in soup.findAll('div', attrs={'class':'title'}): + text_link = item.parent.find('img',attrs={'alt':'Text'}) + if text_link: + url = self.LOGIN + item.a['href'] + title = item.a.contents[0] + date = strftime(' %B %Y') + articles.append({ + 'title' :title + ,'date' :date + ,'url' :url + ,'description':'' + }) + return [(soup.head.title.string, articles)] \ No newline at end of file diff --git a/src/calibre/web/feeds/templates.py b/src/calibre/web/feeds/templates.py index d1bd593956..b6b0200a66 100644 --- a/src/calibre/web/feeds/templates.py +++ b/src/calibre/web/feeds/templates.py @@ -144,9 +144,9 @@ class FeedTemplate(Template):
  • ${article.title} -

    +

    ${Markup(cutoff(article.summary))} -

    +
  • From a06522c486b97d6268bc268c6970201c441c63a6 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 8 Dec 2008 17:30:33 -0800 Subject: [PATCH 2/4] IGN:Add spacing to article list in downloaded feeds --- src/calibre/web/feeds/templates.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/web/feeds/templates.py b/src/calibre/web/feeds/templates.py index b6b0200a66..4cc79a8b89 100644 --- a/src/calibre/web/feeds/templates.py +++ b/src/calibre/web/feeds/templates.py @@ -141,7 +141,7 @@ class FeedTemplate(Template):
      -
    • +
    • ${article.title}
      From e90cb0954b27fd964acf2a29aed3bb7189bc7dec Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 8 Dec 2008 17:31:33 -0800 Subject: [PATCH 3/4] IGN:Make locations view a little prettier --- src/calibre/gui2/main.ui | 19 +++++++----- src/calibre/gui2/widgets.py | 60 ++++++++----------------------------- 2 files changed, 23 insertions(+), 56 deletions(-) diff --git a/src/calibre/gui2/main.ui b/src/calibre/gui2/main.ui index a4541f0a1d..18d6f5228d 100644 --- a/src/calibre/gui2/main.ui +++ b/src/calibre/gui2/main.ui @@ -46,8 +46,8 @@ - 10000 - 110 + 16777215 + 100 @@ -74,14 +74,17 @@ QListView::LeftToRight - - false - - - 10 + + + 175 + 90 + - QListView::IconMode + QListView::ListMode + + + true diff --git a/src/calibre/gui2/widgets.py b/src/calibre/gui2/widgets.py index 5b3c2afe8f..224077072e 100644 --- a/src/calibre/gui2/widgets.py +++ b/src/calibre/gui2/widgets.py @@ -7,9 +7,9 @@ import re, os, traceback from PyQt4.QtGui import QListView, QIcon, QFont, QLabel, QListWidget, \ QListWidgetItem, QTextCharFormat, QApplication, \ QSyntaxHighlighter, QCursor, QColor, QWidget, QDialog, \ - QAbstractItemDelegate, QPixmap, QStyle, QFontMetrics + QPixmap from PyQt4.QtCore import QAbstractListModel, QVariant, Qt, SIGNAL, \ - QObject, QRegExp, QString, QSettings + QObject, QRegExp, QString, QSettings, QSize from calibre.gui2.jobs2 import DetailView from calibre.gui2 import human_readable, NONE, TableView, \ @@ -128,56 +128,17 @@ class ImageView(QLabel): self.setMaximumWidth(width) self.setMaximumHeight(height) -class LocationDelegate(QAbstractItemDelegate): - - def __init__(self): - QAbstractItemDelegate.__init__(self) - self.pixmap = QPixmap(40, 40) - self.text = QString('Reader\n999.9 MB Available202') - - def rects(self, option): - style = QApplication.style() - font = QFont(option.font) - font.setBold(True) - irect = style.itemPixmapRect(option.rect, Qt.AlignHCenter|Qt.AlignTop, self.pixmap) - trect = style.itemTextRect(QFontMetrics(font), option.rect, - Qt.AlignHCenter|Qt.AlignTop, True, self.text) - trect.moveTop(irect.bottom()) - return irect, trect - - def sizeHint(self, option, index): - irect, trect = self.rects(option) - return irect.united(trect).size() - - def paint(self, painter, option, index): - style = QApplication.style() - painter.save() - if hasattr(QStyle, 'CE_ItemViewItem'): - QApplication.style().drawControl(QStyle.CE_ItemViewItem, option, painter) - highlight = getattr(index.model(), 'highlight_row', -1) == index.row() - mode = QIcon.Active if highlight else QIcon.Normal - pixmap = QIcon(index.model().data(index, Qt.DecorationRole)).pixmap(self.pixmap.size()) - pixmap = style.generatedIconPixmap(mode, pixmap, option) - text = index.model().data(index, Qt.DisplayRole).toString() - irect, trect = self.rects(option) - style.drawItemPixmap(painter, irect, Qt.AlignHCenter|Qt.AlignTop, pixmap) - font = QFont(option.font) - font.setBold(highlight) - painter.setFont(font) - style.drawItemText(painter, trect, Qt.AlignHCenter|Qt.AlignBottom, - option.palette, True, text) - painter.restore() - class LocationModel(QAbstractListModel): + def __init__(self, parent): QAbstractListModel.__init__(self, parent) self.icons = [QVariant(QIcon(':/library')), QVariant(QIcon(':/images/reader.svg')), QVariant(QIcon(':/images/sd.svg'))] self.text = [_('Library'), - _('Reader\n%s available'), - _('Card\n%s available')] + _('Reader\n%s\navailable'), + _('Card\n%s\navailable')] self.free = [-1, -1] self.highlight_row = 0 self.tooltips = [ @@ -199,7 +160,13 @@ class LocationModel(QAbstractListModel): elif role == Qt.DecorationRole: data = self.icons[row] elif role == Qt.ToolTipRole: - return QVariant(self.tooltips[row]) + data = QVariant(self.tooltips[row]) + elif role == Qt.SizeHintRole: + data = QVariant(QSize(155, 90)) + elif role == Qt.FontRole: + font = QFont('monospace') + font.setBold(row == self.highlight_row) + data = QVariant(font) return data def headerData(self, section, orientation, role): @@ -223,8 +190,6 @@ class LocationView(QListView): self.setModel(LocationModel(self)) self.reset() QObject.connect(self.selectionModel(), SIGNAL('currentChanged(QModelIndex, QModelIndex)'), self.current_changed) - self.delegate = LocationDelegate() - self.setItemDelegate(self.delegate) self.setCursor(Qt.PointingHandCursor) def current_changed(self, current, previous): @@ -270,7 +235,6 @@ class FontFamilyModel(QAbstractListModel): try: family = self.families[index.row()] except: - import traceback traceback.print_exc() return NONE if role == Qt.DisplayRole: From 463b406312c488c02ea35152f766385fb26bd8a4 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 9 Dec 2008 03:25:31 -0800 Subject: [PATCH 4/4] Use python 2.6 and Visual Studio 2008 in the windows build --- installer/windows/freeze.py | 25 ++++++--- pyqtdistutils.py | 59 ++++++++++++++++---- setup.py | 10 ++-- src/calibre/devices/libusb.py | 9 ++- src/calibre/gui2/pictureflow/pictureflow.cpp | 6 +- src/calibre/libunrar.py | 7 ++- todo-2.6 | 2 - 7 files changed, 85 insertions(+), 33 deletions(-) diff --git a/installer/windows/freeze.py b/installer/windows/freeze.py index 007217803e..73bb9cae56 100644 --- a/installer/windows/freeze.py +++ b/installer/windows/freeze.py @@ -6,13 +6,13 @@ __docformat__ = 'restructuredtext en' ''' Freeze app into executable using py2exe. ''' -QT_DIR = 'C:\\Qt\\4.4.1' +QT_DIR = 'C:\\Qt\\4.4.3' LIBUSB_DIR = 'C:\\libusb' LIBUNRAR = 'C:\\Program Files\\UnrarDLL\\unrar.dll' PDFTOHTML = 'C:\\pdftohtml\\pdftohtml.exe' IMAGEMAGICK_DIR = 'C:\\ImageMagick' FONTCONFIG_DIR = 'C:\\fontconfig' - +VC90 = r'C:\Program Files\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.CRT' import sys, os, py2exe, shutil, zipfile, glob, subprocess, re from distutils.core import setup @@ -65,6 +65,8 @@ class BuildEXE(py2exe.build_exe.py2exe): shutil.copyfile(f, os.path.join(self.dist_dir, os.path.basename(f))) for f in glob.glob(os.path.join(BASE_DIR, 'src', 'calibre', 'plugins', '*.pyd')): shutil.copyfile(f, os.path.join(tgt, os.path.basename(f))) + for f in glob.glob(os.path.join(BASE_DIR, 'src', 'calibre', 'plugins', '*.manifest')): + shutil.copyfile(f, os.path.join(tgt, os.path.basename(f))) shutil.copyfile('LICENSE', os.path.join(self.dist_dir, 'LICENSE')) print print 'Adding QtXml4.dll' @@ -115,12 +117,17 @@ class BuildEXE(py2exe.build_exe.py2exe): shutil.copytree(f, tgt) else: shutil.copyfile(f, tgt) - + print print 'Doing DLL redirection' # See http://msdn.microsoft.com/en-us/library/ms682600(VS.85).aspx for f in glob.glob(os.path.join(PY2EXE_DIR, '*.exe')): open(f + '.local', 'w').write('\n') + print + print 'Adding Windows runtime dependencies...' + for f in glob.glob(os.path.join(VC90, '*')): + shutil.copyfile(f, os.path.join(PY2EXE_DIR, os.path.basename(f))) + @classmethod def manifest(cls, prog): @@ -142,17 +149,17 @@ def main(args=sys.argv): {'script' : scripts['gui'][0], 'dest_base' : APPNAME, 'icon_resources' : [(1, ICONS[0])], - 'other_resources' : [BuildEXE.manifest(APPNAME)], + #'other_resources' : [BuildEXE.manifest(APPNAME)], }, {'script' : scripts['gui'][1], 'dest_base' : 'lrfviewer', 'icon_resources' : [(1, ICONS[1])], - 'other_resources' : [BuildEXE.manifest('lrfviewer')], + #'other_resources' : [BuildEXE.manifest('lrfviewer')], }, {'script' : scripts['gui'][2], 'dest_base' : 'ebook-viewer', 'icon_resources' : [(1, ICONS[1])], - 'other_resources' : [BuildEXE.manifest('ebook-viewer')], + #'other_resources' : [BuildEXE.manifest('ebook-viewer')], }, ], console = console, @@ -162,12 +169,12 @@ def main(args=sys.argv): 'includes' : [ 'sip', 'pkg_resources', 'PyQt4.QtSvg', 'mechanize', 'ClientForm', 'wmi', - 'win32file', 'pythoncom', 'rtf2xml', + 'win32file', 'pythoncom', 'win32process', 'win32api', 'msvcrt', 'win32event', 'calibre.ebooks.lrf.any.*', 'calibre.ebooks.lrf.feeds.*', - 'genshi', 'BeautifulSoup', - 'path', 'pydoc', 'IPython.Extensions.*', + 'BeautifulSoup', 'pyreadline', + 'pydoc', 'IPython.Extensions.*', 'calibre.web.feeds.recipes.*', 'PyQt4.QtWebKit', 'PyQt4.QtNetwork', ], diff --git a/pyqtdistutils.py b/pyqtdistutils.py index 252968fb60..0e53aaabfe 100644 --- a/pyqtdistutils.py +++ b/pyqtdistutils.py @@ -6,7 +6,7 @@ __docformat__ = 'restructuredtext en' ''' Build PyQt extensions. Integrates with distutils (but uses the PyQt build system). ''' -from distutils.core import Extension +from distutils.core import Extension as _Extension from distutils.command.build_ext import build_ext as _build_ext from distutils.dep_util import newer_group from distutils import log @@ -15,12 +15,23 @@ import sipconfig, os, sys, string, glob, shutil from PyQt4 import pyqtconfig iswindows = 'win32' in sys.platform QMAKE = os.path.expanduser('~/qt/bin/qmake') if 'darwin' in sys.platform else'qmake' -WINDOWS_PYTHON = ['C:/Python25/libs'] +WINDOWS_PYTHON = ['C:/Python26/libs'] OSX_SDK = '/Developer/SDKs/MacOSX10.4u.sdk' def replace_suffix(path, new_suffix): return os.path.splitext(path)[0] + new_suffix +class Extension(_Extension): + pass + +if iswindows: + from distutils import msvc9compiler + msvc = msvc9compiler.MSVCCompiler() + msvc.initialize() + nmake = msvc.find_exe('nmake.exe') + rc = msvc.find_exe('rc.exe') + + class PyQtExtension(Extension): def __init__(self, name, sources, sip_sources, **kw): @@ -37,9 +48,7 @@ class PyQtExtension(Extension): class build_ext(_build_ext): def make(self, makefile): - make = 'make' - if iswindows: - make = 'mingw32-make' + make = nmake if iswindows else 'make' self.spawn([make, '-f', makefile]) def build_qt_objects(self, ext, bdir): @@ -65,12 +74,13 @@ CONFIG += x86 ppc open(name+'.pro', 'wb').write(pro) self.spawn([QMAKE, '-o', 'Makefile.qt', name+'.pro']) self.make('Makefile.qt') - pat = 'release\\*.o' if iswindows else '*.o' + pat = 'release\\*.obj' if iswindows else '*.o' return map(os.path.abspath, glob.glob(pat)) finally: os.chdir(cwd) def build_sbf(self, sip, sbf, bdir): + print '\tBuilding spf...' sip_bin = self.sipcfg.sip_bin self.spawn([sip_bin, "-c", bdir, @@ -100,9 +110,7 @@ CONFIG += x86 ppc def build_extension(self, ext): self.inplace = True # Causes extensions to be built in the source tree - if not isinstance(ext, PyQtExtension): - return _build_ext.build_extension(self, ext) - + fullname = self.get_ext_fullname(ext.name) if self.inplace: # ignore build-lib -- put the compiled extension into @@ -119,7 +127,38 @@ CONFIG += x86 ppc else: ext_filename = os.path.join(self.build_lib, self.get_ext_filename(fullname)) - bdir = os.path.abspath(os.path.join(self.build_temp, fullname)) + bdir = os.path.abspath(os.path.join(self.build_temp, fullname)) + if not os.path.exists(bdir): + os.makedirs(bdir) + + if not isinstance(ext, PyQtExtension): + if not iswindows: + return _build_ext.build_extension(self, ext) + + c_sources = [f for f in ext.sources if os.path.splitext(f)[1].lower() in ('.c', '.cpp', '.cxx')] + compile_args = '/c /nologo /Ox /MD /W3 /GX /DNDEBUG'.split() + compile_args += ext.extra_compile_args + self.swig_opts = '' + inc_dirs = self.include_dirs + [x.replace('/', '\\') for x in ext.include_dirs] + cc = [msvc.cc] + compile_args + ['-I%s'%x for x in list(set(inc_dirs))] + objects = [] + for f in c_sources: + o = os.path.join(bdir, os.path.basename(f)+'.obj') + objects.append(o) + compiler = cc + ['/Tc'+f, '/Fo'+o] + self.spawn(compiler) + out = os.path.join(bdir, base+'.pyd') + linker = [msvc.linker] + '/DLL /nologo /INCREMENTAL:NO'.split() + linker += ['/LIBPATH:'+x for x in self.library_dirs] + linker += [x+'.lib' for x in ext.libraries] + linker += ['/EXPORT:init'+base] + objects + ['/OUT:'+out] + self.spawn(linker) + for src in (out, out+'.manifest'): + shutil.copyfile(src, os.path.join('src', 'calibre', 'plugins', os.path.basename(src))) + return + + + if not os.path.exists(bdir): os.makedirs(bdir) ext.sources2 = map(os.path.abspath, ext.sources) diff --git a/setup.py b/setup.py index 37d54c4317..ca704d0916 100644 --- a/setup.py +++ b/setup.py @@ -46,10 +46,10 @@ main_functions = { } if __name__ == '__main__': - from setuptools import setup, find_packages, Extension + from setuptools import setup, find_packages from distutils.command.build import build as _build from distutils.core import Command as _Command - from pyqtdistutils import PyQtExtension, build_ext + from pyqtdistutils import PyQtExtension, build_ext, Extension import subprocess, glob def newer(targets, sources): @@ -391,8 +391,10 @@ if __name__ == '__main__': ext_modules.append(Extension('calibre.plugins.winutil', sources=['src/calibre/utils/windows/winutil.c'], libraries=['shell32', 'setupapi'], - include_dirs=['C:/WinDDK/6001.18001/inc/api/']) - ) + include_dirs=['C:/WinDDK/6001.18001/inc/api/', + 'C:/WinDDK/6001.18001/inc/crt/'], + extra_compile_args=['/X'] + )) if isosx: ext_modules.append(Extension('calibre.plugins.usbobserver', sources=['src/calibre/devices/usbobserver/usbobserver.c']) diff --git a/src/calibre/devices/libusb.py b/src/calibre/devices/libusb.py index 0bedce32bb..226a99f239 100644 --- a/src/calibre/devices/libusb.py +++ b/src/calibre/devices/libusb.py @@ -4,17 +4,20 @@ __copyright__ = '2008, Kovid Goyal ' This module provides a thin ctypes based wrapper around libusb. """ -from ctypes import cdll, POINTER, byref, pointer, Structure, \ +from ctypes import cdll, POINTER, byref, pointer, Structure as _Structure, \ c_ubyte, c_ushort, c_int, c_char, c_void_p, c_byte, c_uint from errno import EBUSY, ENOMEM -from calibre import iswindows, isosx, load_library, isfrozen +from calibre import iswindows, isosx, load_library _libusb_name = 'libusb' PATH_MAX = 511 if iswindows else 1024 if isosx else 4096 if iswindows: - Structure._pack_ = 1 + class Structure(_Structure): + _pack_ = 1 _libusb_name = 'libusb0' +else: + Structure = _Structure try: try: diff --git a/src/calibre/gui2/pictureflow/pictureflow.cpp b/src/calibre/gui2/pictureflow/pictureflow.cpp index a6b28146e9..3d2b0286c0 100644 --- a/src/calibre/gui2/pictureflow/pictureflow.cpp +++ b/src/calibre/gui2/pictureflow/pictureflow.cpp @@ -715,7 +715,7 @@ void PictureFlowPrivate::render() painter.setPen(Qt::white); //painter.setPen(QColor(255,255,255,127)); - if (centerIndex < slideCount() and centerIndex > -1) + if (centerIndex < slideCount() && centerIndex > -1) painter.drawText( QRect(0,0, buffer.width(), (buffer.height() - slideSize().height())/2), Qt::AlignCenter, slideImages->caption(centerIndex)); @@ -767,12 +767,12 @@ void PictureFlowPrivate::render() int sc = slideCount(); painter.setPen(QColor(255,255,255, (255-fade) )); - if (leftTextIndex < sc and leftTextIndex > -1) + if (leftTextIndex < sc && leftTextIndex > -1) painter.drawText( QRect(0,0, buffer.width(), (buffer.height() - slideSize().height())/2), Qt::AlignCenter, slideImages->caption(leftTextIndex)); painter.setPen(QColor(255,255,255, fade)); - if (leftTextIndex+1 < sc and leftTextIndex > -2) + if (leftTextIndex+1 < sc && leftTextIndex > -2) painter.drawText( QRect(0,0, buffer.width(), (buffer.height() - slideSize().height())/2), Qt::AlignCenter, slideImages->caption(leftTextIndex+1)); diff --git a/src/calibre/libunrar.py b/src/calibre/libunrar.py index bb324282c3..7c608b72f1 100644 --- a/src/calibre/libunrar.py +++ b/src/calibre/libunrar.py @@ -7,7 +7,7 @@ This module provides a thin ctypes based wrapper around libunrar. See ftp://ftp.rarlabs.com/rar/unrarsrc-3.7.5.tar.gz """ import os, ctypes, sys, re -from ctypes import Structure, c_char_p, c_uint, c_void_p, POINTER, \ +from ctypes import Structure as _Structure, c_char_p, c_uint, c_void_p, POINTER, \ byref, c_wchar_p, c_int, c_char, c_wchar from tempfile import NamedTemporaryFile from StringIO import StringIO @@ -18,9 +18,12 @@ from calibre.ptempfile import TemporaryDirectory _librar_name = 'libunrar' cdll = ctypes.cdll if iswindows: - Structure._pack_ = 1 + class Structure(_Structure): + _pack_ = 1 _librar_name = 'unrar' cdll = ctypes.windll +else: + Structure = _Structure if hasattr(sys, 'frozen') and iswindows: _libunrar = cdll.LoadLibrary(os.path.join(os.path.dirname(sys.executable), 'unrar.dll')) _libunrar = load_library(_librar_name, cdll) diff --git a/todo-2.6 b/todo-2.6 index 00ed1d0e26..33b5a5e428 100644 --- a/todo-2.6 +++ b/todo-2.6 @@ -5,5 +5,3 @@ * Use multiprocessing for cpu_count instead of QThread -* Windows build: - * Compile all dependencies with MSVC 2008 since this is what python now uses