diff --git a/session.vim b/session.vim index 50c2d5285e..56705f9528 100644 --- a/session.vim +++ b/session.vim @@ -1,5 +1,5 @@ " Project wide builtins -let g:pyflakes_builtins += ["dynamic_property", "__", "P"] +let g:pyflakes_builtins += ["dynamic_property", "__", "P", "I"] python << EOFPY import os diff --git a/setup.py b/setup.py index 516a3ad198..d5cf8a406a 100644 --- a/setup.py +++ b/setup.py @@ -22,8 +22,23 @@ def check_version_info(): def option_parser(): parser = optparse.OptionParser() + parser.add_option('-c', '--clean', default=False, action='store_true', + help=('Instead of running the command delete all files generated ' + 'by the command')) + parser.add_option('--clean-backups', default=False, action='store_true', + help='Delete all backup files from the source tree') + parser.add_option('--clean-all', default=False, action='store_true', + help='Delete all machine generated files from the source tree') return parser +def clean_backups(): + for root, _, files in os.walk('.'): + for name in files: + for t in ('.pyc', '.pyo', '~', '.swp', '.swo'): + if name.endswith(t): + os.remove(os.path.join(root, name)) + + def main(args=sys.argv): if len(args) == 1 or args[1] in ('-h', '--help'): print 'Usage: python', args[0], 'command', '[options]' @@ -46,6 +61,21 @@ def main(args=sys.argv): command.description) opts, args = parser.parse_args(args) + + if opts.clean_backups: + clean_backups() + + if opts.clean: + prints('Cleaning', args[1]) + command.clean() + return 0 + + if opts.clean_all(): + for cmd in commands.__all__: + prints('Cleaning', cmd) + getattr(commands, cmd).clean() + return 0 + command.run_all(opts) warnings = get_warnings() diff --git a/setup/commands.py b/setup/commands.py index 1d71d4753e..de44c75538 100644 --- a/setup/commands.py +++ b/setup/commands.py @@ -11,13 +11,10 @@ __all__ = [ 'build', 'gui', 'develop', - 'clean', 'clean_backups', ] -import os, shutil from setup.translations import POT, GetTranslations, Translations, ISO639 -from setup import Command pot = POT() translations = Translations() get_translations = GetTranslations() @@ -32,50 +29,6 @@ develop = Develop() from setup.gui import GUI gui = GUI() -class CleanBackups(Command): - - description='Delete all backup files in the calibre source tree' - - def clean(self): - return self.run(None) - - def run(self, opts=None): - for root, _, files in os.walk(self.d(self.SRC)): - for name in files: - for t in ('.pyc', '.pyo', '~', '.swp', '.swo'): - if name.endswith(t): - os.remove(os.path.join(root, name)) - -clean_backups = CleanBackups() - -class Clean(Command): - - description='''Delete all computer generated files in the source tree''' - - sub_commands = __all__ - - def add_options(self, parser): - opt = parser.remove_option('--only') - help = 'Only run clean for the specified command. Choices: '+\ - ', '.join(__all__) - parser.add_option('-1', '--only', default='all', - choices=__all__+['all'], help=help) - - def run_all(self, opts): - self.info('Cleaning...') - only = None if opts.only == 'all' else commands[opts.only] - for cmd in self.sub_commands: - if only is not None and only is not cmd: - continue - self.info('\tCleaning', command_names[cmd]) - cmd.clean() - - def clean(self): - for dir in ('dist', os.path.join('src', 'calibre.egg-info')): - shutil.rmtree(dir, ignore_errors=True) - -clean = Clean() - commands = {} for x in __all__: diff --git a/setup/gui.py b/setup/gui.py index 5dd53e4cdd..d3c4071ffd 100644 --- a/setup/gui.py +++ b/setup/gui.py @@ -55,30 +55,30 @@ class GUI(Command): def build_forms(self): from PyQt4.uic import compileUi forms = self.find_forms() + pat = re.compile(r'''(['"]):/images/([^'"]+)\1''') + def sub(match): + ans = 'I(%s%s%s)'%(match.group(1), match.group(2), match.group(1)) + return ans + for form in forms: compiled_form = self.form_to_compiled_form(form) if not os.path.exists(compiled_form) or os.stat(form).st_mtime > os.stat(compiled_form).st_mtime: - print 'Compiling form', form + self.info('\tCompiling form', form) buf = cStringIO.StringIO() compileUi(form, buf) dat = buf.getvalue() dat = dat.replace('__appname__', __appname__) - dat = dat.replace('import images_rc', 'from calibre.gui2 import images_rc') + dat = dat.replace('import images_rc', '') dat = dat.replace('from library import', 'from calibre.gui2.library import') dat = dat.replace('from widgets import', 'from calibre.gui2.widgets import') dat = dat.replace('from convert.xpath_wizard import', 'from calibre.gui2.convert.xpath_wizard import') dat = re.compile(r'QtGui.QApplication.translate\(.+?,\s+"(.+?)(? 1 else None, diff --git a/src/calibre/gui2/widgets.py b/src/calibre/gui2/widgets.py index d2a24ddebc..c0f8b13e44 100644 --- a/src/calibre/gui2/widgets.py +++ b/src/calibre/gui2/widgets.py @@ -27,7 +27,7 @@ class ProgressIndicator(QWidget): def __init__(self, *args): QWidget.__init__(self, *args) self.setGeometry(0, 0, 300, 350) - self.movie = QMovie(':/images/jobs-animated.mng') + self.movie = QMovie(I('jobs-animated.mng')) self.ml = QLabel(self) self.ml.setMovie(self.movie) self.movie.start() @@ -159,10 +159,10 @@ class LocationModel(QAbstractListModel): def __init__(self, parent): QAbstractListModel.__init__(self, parent) - self.icons = [QVariant(QIcon(':/images/library.png')), - QVariant(QIcon(':/images/reader.svg')), - QVariant(QIcon(':/images/sd.svg')), - QVariant(QIcon(':/images/sd.svg'))] + self.icons = [QVariant(QIcon(I('library.png'))), + QVariant(QIcon(I('reader.svg'))), + QVariant(QIcon(I('sd.svg'))), + QVariant(QIcon(I('sd.svg')))] self.text = [_('Library\n%d\nbooks'), _('Reader\n%s\navailable'), _('Card A\n%s\navailable'), @@ -313,7 +313,7 @@ class EjectButton(QAbstractButton): def paintEvent(self, event): painter = QPainter(self) painter.setClipRect(event.rect()) - image = QPixmap(':/images/eject').scaledToHeight(event.rect().height(), + image = QPixmap(I('eject')).scaledToHeight(event.rect().height(), Qt.SmoothTransformation) if not self.mouse_over: diff --git a/src/calibre/gui2/wizard/__init__.py b/src/calibre/gui2/wizard/__init__.py index f4aea4268f..df7cdc7fd6 100644 --- a/src/calibre/gui2/wizard/__init__.py +++ b/src/calibre/gui2/wizard/__init__.py @@ -532,8 +532,8 @@ class Wizard(QWizard): self.setPixmap(self.LogoPixmap, p.scaledToHeight(80, Qt.SmoothTransformation)) self.setPixmap(self.WatermarkPixmap, - QPixmap(':/images/welcome_wizard.svg')) - self.setPixmap(self.BackgroundPixmap, QPixmap(':/images/wizard.svg')) + QPixmap(I('welcome_wizard.svg'))) + self.setPixmap(self.BackgroundPixmap, QPixmap(I('wizard.svg'))) self.device_page = DevicePage() self.library_page = LibraryPage() self.finish_page = FinishPage() diff --git a/src/calibre/linux.py b/src/calibre/linux.py index 53e15dcfd6..73fbbc6e00 100644 --- a/src/calibre/linux.py +++ b/src/calibre/linux.py @@ -428,7 +428,6 @@ def render_svg(image, dest): def setup_desktop_integration(fatal_errors): try: from PyQt4.QtCore import QFile - from calibre.gui2 import images_rc # Load images from tempfile import mkdtemp print 'Setting up desktop integration...' @@ -438,12 +437,12 @@ def setup_desktop_integration(fatal_errors): cwd = os.getcwdu() try: os.chdir(tdir) - render_svg(QFile(':/images/mimetypes/lrf.svg'), os.path.join(tdir, 'calibre-lrf.png')) + render_svg(QFile(I('mimetypes/lrf.svg')), os.path.join(tdir, 'calibre-lrf.png')) check_call('xdg-icon-resource install --context mimetypes --size 128 calibre-lrf.png application-lrf', shell=True) check_call('xdg-icon-resource install --context mimetypes --size 128 calibre-lrf.png text-lrs', shell=True) - QFile(':library').copy(os.path.join(tdir, 'calibre-gui.png')) + QFile(I('library.png')).copy(os.path.join(tdir, 'calibre-gui.png')) check_call('xdg-icon-resource install --size 128 calibre-gui.png calibre-gui', shell=True) - render_svg(QFile(':/images/viewer.svg'), os.path.join(tdir, 'calibre-viewer.png')) + render_svg(QFile(I('viewer.svg')), os.path.join(tdir, 'calibre-viewer.png')) check_call('xdg-icon-resource install --size 128 calibre-viewer.png calibre-viewer', shell=True) f = open('calibre-lrfviewer.desktop', 'wb') diff --git a/src/calibre/translations/dynamic.py b/src/calibre/translations/dynamic.py index 6131a84c8f..c1f368ff5a 100644 --- a/src/calibre/translations/dynamic.py +++ b/src/calibre/translations/dynamic.py @@ -5,9 +5,10 @@ Dynamic language lookup of translations for user-visible strings. __license__ = 'GPL v3' __copyright__ = '2008, Marshall T. Vandegrift ' -from cStringIO import StringIO +import os + from gettext import GNUTranslations -from calibre.translations.compiled import translations +from calibre.utils.localization import get_lc_messages_path __all__ = ['translate'] @@ -17,10 +18,13 @@ def translate(lang, text): trans = None if lang in _CACHE: trans = _CACHE[lang] - elif lang in translations: - buf = StringIO(translations[lang]) - trans = GNUTranslations(buf) - _CACHE[lang] = trans + else: + mpath = get_lc_messages_path(lang) + if mpath is not None: + p = os.path.join(mpath, 'messages.mo') + if os.path.exists(p): + trans = GNUTranslations(open(p, 'rb')) + _CACHE[lang] = trans if trans is None: return getattr(__builtins__, '_', lambda x: x)(text) return trans.ugettext(text) diff --git a/src/calibre/utils/localization.py b/src/calibre/utils/localization.py index 4090605341..b4323e0a65 100644 --- a/src/calibre/utils/localization.py +++ b/src/calibre/utils/localization.py @@ -44,6 +44,19 @@ def get_lang(): def messages_path(lang): return P('localization/locales/%s/LC_MESSAGES'%lang) +def get_lc_messages_path(lang): + hlang = None + if lang in available_translations(): + hlang = lang + else: + xlang = lang.split('_')[0] + if xlang in available_translations(): + hlang = xlang + if hlang is not None: + return messages_path(hlang) + return None + + def set_translators(): # To test different translations invoke as # CALIBRE_OVERRIDE_LANG=de_DE.utf8 program @@ -57,20 +70,12 @@ def set_translators(): make(lang+'.po', buf) buf = cStringIO.StringIO(buf.getvalue()) - hlang = None - if lang in available_translations(): - hlang = lang - else: - xlang = lang.split('_')[0] - if xlang in available_translations(): - hlang = xlang - if hlang is not None: + mpath = get_lc_messages_path(lang) + if mpath is not None: if buf is None: - buf = open(os.path.join(messages_path(hlang), - 'messages.mo'), 'rb') - if hlang == 'nds': - hlang = 'de' - isof = os.path.join(messages_path(hlang), 'iso639.mo') + buf = open(os.path.join(mpath, 'messages.mo'), 'rb') + mpath = mpath.replace(os.sep+'nds'+os.sep, os.sep+'de'+os.sep) + isof = os.path.join(mpath, 'iso639.mo') if os.path.exists(isof): iso639 = open(isof, 'rb') @@ -115,8 +120,9 @@ def set_qt_translator(translator): if lang is not None: if lang == 'nds': lang = 'de' - for x in (lang, lang.split('_')[0]): - p = os.path.join(messages_path(x), 'qt.qm') + mpath = get_lc_messages_path(lang) + if mpath is not None: + p = os.path.join(mpath, 'qt.qm') if os.path.exists(p): return translator.load(p) return False diff --git a/src/calibre/utils/resources.py b/src/calibre/utils/resources.py index 98f056e065..0baaac014b 100644 --- a/src/calibre/utils/resources.py +++ b/src/calibre/utils/resources.py @@ -13,5 +13,8 @@ def get_path(path): path = path.replace(os.sep, '/') return os.path.join(sys.resources_location, *path.split('/')) -__builtin__.__dict__['P'] = get_path +def get_image_path(path): + return get_path('images/'+path) +__builtin__.__dict__['P'] = get_path +__builtin__.__dict__['I'] = get_image_path diff --git a/src/calibre/web/feeds/news.py b/src/calibre/web/feeds/news.py index 4e81f15d89..f28a41a7cb 100644 --- a/src/calibre/web/feeds/news.py +++ b/src/calibre/web/feeds/news.py @@ -13,8 +13,6 @@ from functools import partial from contextlib import nested, closing from datetime import datetime -from PyQt4.Qt import QApplication, QFile, QIODevice - from calibre import browser, __appname__, iswindows, \ strftime, __version__, preferred_encoding @@ -812,17 +810,11 @@ class BasicNewsRecipe(Recipe): from calibre.gui2 import is_ok_to_use_qt if not is_ok_to_use_qt(): return False - from calibre.gui2 import images_rc # Needed for access to logo - images_rc - if QApplication.instance() is None: QApplication([]) - f = QFile(':/library') - f.open(QIODevice.ReadOnly) - img_data = str(f.readAll()) + img_data = open(I('library.png'), 'rb').read() tdir = PersistentTemporaryDirectory('_default_cover') img = os.path.join(tdir, 'logo.png') with open(img, 'wb') as g: g.write(img_data) - f.close() img = os.path.basename(img) html= u'''\