From 675510e428dced8195e13b481fe7ee05940a8a46 Mon Sep 17 00:00:00 2001 From: "Marshall T. Vandegrift" Date: Mon, 21 Jul 2008 19:42:40 -0400 Subject: [PATCH 01/34] Switch to RE-based unescaped ampersand post-processing --- src/calibre/ebooks/lit/reader.py | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/src/calibre/ebooks/lit/reader.py b/src/calibre/ebooks/lit/reader.py index 2850b05a2b..5d464e0186 100644 --- a/src/calibre/ebooks/lit/reader.py +++ b/src/calibre/ebooks/lit/reader.py @@ -10,6 +10,7 @@ __copyright__ = '2008, Kovid Goyal ' \ import sys, struct, cStringIO, os import functools import codecs +import re from itertools import repeat from calibre import relpath @@ -98,33 +99,21 @@ def read_utf8_char(bytes, pos): return unichr(c), pos+elsize class UnBinary(object): + AMPERSAND_RE = re.compile( + r'&(?!(?:#[0-9]+|#x[0-9a-fA-F]+|[a-zA-Z_:][a-zA-Z0-9.-_:]+);)') + def __init__(self, bin, manifest, map=OPF_MAP): self.manifest = manifest self.tag_map, self.attr_map, self.tag_to_attr_map = map self.opf = map is OPF_MAP self.bin = bin self.buf = cStringIO.StringIO() - self.ampersands = [] self.binary_to_text() self.raw = self.buf.getvalue().lstrip().decode('utf-8') self.escape_ampersands() def escape_ampersands(self): - offset = 0 - for pos in self.ampersands: - test = self.raw[pos+offset:pos+offset+6] - if test.startswith('&#') and ';' in test: - continue - escape = True - for ent in XML_ENTITIES: - if test.startswith(ent): - escape = False - break - if not escape: - continue - self.raw = '&'.join( - (self.raw[:pos+offset], self.raw[pos+offset+1:])) - offset += 4 + self.raw = self.AMPERSAND_RE.sub('&', self.raw) def item_path(self, internal_id): try: @@ -153,8 +142,6 @@ class UnBinary(object): continue elif c == '\v': c = '\n' - elif c == '&': - self.ampersands.append(self.buf.tell()-1) self.buf.write(c.encode('utf-8')) elif state == 'get flags': From 4582b165d6d5fffa2ffc8921127acf116831f0b0 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 21 Jul 2008 19:45:09 -0700 Subject: [PATCH 02/34] IGN:Fix translation bugs --- src/calibre/translations/es.po | 26 +++++++++++++++----------- src/calibre/translations/it.po | 9 ++++++--- src/calibre/translations/nl.po | 28 ++++++++++++++++++---------- src/calibre/translations/ru.po | 2 ++ 4 files changed, 41 insertions(+), 24 deletions(-) diff --git a/src/calibre/translations/es.po b/src/calibre/translations/es.po index d5fd04e82f..bda7df14d3 100644 --- a/src/calibre/translations/es.po +++ b/src/calibre/translations/es.po @@ -426,6 +426,7 @@ msgstr "" "Expressión regular utilizada para detectar los títulos de los capítulos. " "Busca las marcas de encabezado (h1-h6). Por defecto: %default" +# (pofilter) escapes: escapes in original ('"h\d,class,chapter".') don't match escapes in translation () #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:165 msgid "" "Detect a chapter beginning at an element having the specified attribute. The " @@ -437,7 +438,7 @@ msgstr "" "especificado. El formato para ésta espresión es tagname regexp, nombre del " "atributo, valor del atributo regexp. Por ejemplo, para encontrar todas las " "etiquetas de cabecera que tienen como attribute class=\"capítulo\" podría " -"usar: \"h/d,class,capítulo\". El valor por defecto es: %default" +"usar: \"h\\d,class,capítulo\". El valor por defecto es: %default" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:167 msgid "" @@ -2111,6 +2112,7 @@ msgstr "&Compartir receta" msgid "&Load recipe from file" msgstr "&Cargar receta desde un archivo" +# (pofilter) xmltags: checks that XML/HTML tags have not been translated #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:215 msgid "" "\n" "

Crear una receta de " -"noticias básica, añadiendo un RSS Feed. Para la mayoría de los feeds, " -"necesitará utilizar el \"modo avanzado\" para una configuración mas " -"detallada del proceso de adquisición de los datos

" +"noticias básica, añadiendo un RSS Feed.
Para la mayoría de los feeds, " +"necesitará utilizar el \"modo avanzado\" para una configuración mas detallada " +"del proceso de adquisición de los datos

" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles_ui.py:219 msgid "Recipe &title:" @@ -2253,9 +2254,10 @@ msgstr "Ninguna coincidencia" msgid "Authors:" msgstr "Autores:" +# (pofilter) xmltags: checks that XML/HTML tags have not been translated #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:106 msgid "Regular expression group name (?P)" -msgstr "Nombre de grupo de expresión regular (?P)" +msgstr "Nombre de grupo de expresión regular (?P)" #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:108 msgid "Series:" @@ -2348,9 +2350,10 @@ msgstr "Formatos" msgid "Book %s of %s." msgstr "Libro %s de %s." +# (pofilter) xmltags: checks that XML/HTML tags have not been translated #: /home/kovid/work/calibre/src/calibre/gui2/library.py:396 msgid "Double click to edit me

" -msgstr "Doble click para editarme" +msgstr "Doble click para editarme

" #: /home/kovid/work/calibre/src/calibre/gui2/library.py:406 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:757 @@ -2898,14 +2901,15 @@ msgstr "ERROR: Excepción no Contemplada" msgid "Add a custom news source" msgstr "Añadir nueva fuente de noticias" +# (pofilter) xmltags: checks that XML/HTML tags have not been translated #: /home/kovid/work/calibre/src/calibre/gui2/news.py:53 msgid "" "

Please enter your username and password for %s
If you do not have one, " "please subscribe to get access to the articles.
Click OK to proceed." msgstr "" -"

Por favor, introduzca el nombre de usuario y contraseña para %s
Si " -"no tiene uno, por favor dese de alta para obtener acceso a los " -"artículos.
Haga click en OK para continuar." +"

Por favor, introduzca el nombre de usuario y contraseña para %s
Si no " +"tiene uno, por favor dese de alta para obtener acceso a los artículos.
" +"Haga click en OK para continuar." #: /home/kovid/work/calibre/src/calibre/gui2/news.py:79 msgid "Custom news sources" diff --git a/src/calibre/translations/it.po b/src/calibre/translations/it.po index d29925e5a2..1729b1a5e6 100644 --- a/src/calibre/translations/it.po +++ b/src/calibre/translations/it.po @@ -1481,6 +1481,7 @@ msgstr "Cambia l'editore di questo libro" msgid "Ta&gs: " msgstr "T&ag: " +# (pofilter) xmltags: checks that XML/HTML tags have not been translated #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:524 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:127 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:271 @@ -1489,7 +1490,7 @@ msgid "" "

They can be any words or phrases, separated by commas." msgstr "" "I tag categorizzano un libro. Questo è particolarmente utile durante le " -"ricerche.
Possono essere qualsiasi parola o frase, separati da una " +"ricerche.

Possono essere qualsiasi parola o frase, separati da una " "virgola" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:525 @@ -2143,6 +2144,7 @@ msgstr "" msgid "Recipe source code (python)" msgstr "Codice sorgente formula (python)" +# (pofilter) xmltags: checks that XML/HTML tags have not been translated #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:97 msgid "" "

Set a regular expression pattern to use when trying to guess ebook " @@ -2154,7 +2156,7 @@ msgstr "" "

Impostare un modello di espressione regolare da usare nel tentativo di " "indovinare i metadati dei libri dal nome del file.

È disponibile un riferimento sulla " -"sintassi delle espressioni regolari. Usare la funzionalità Test " +"sintassi delle espressioni regolari.

Usare la funzionalità Test " "sottostante per testare le proprie espressioni regolari su una serie di nomi " "di file di esempio." @@ -2294,9 +2296,10 @@ msgstr "Formati" msgid "Book %s of %s." msgstr "Libro %s di %s" +# (pofilter) xmltags: checks that XML/HTML tags have not been translated #: /home/kovid/work/calibre/src/calibre/gui2/library.py:396 msgid "Double click to edit me

" -msgstr "Doppio clic per modificarmi" +msgstr "Doppio clic per modificarmi

" #: /home/kovid/work/calibre/src/calibre/gui2/library.py:406 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:757 diff --git a/src/calibre/translations/nl.po b/src/calibre/translations/nl.po index 4b5ecac7ef..f07545c35a 100644 --- a/src/calibre/translations/nl.po +++ b/src/calibre/translations/nl.po @@ -332,6 +332,7 @@ msgstr "" "De reguliere expressie die wordt gebruikt om hoofdstukken te herkennen. Deze " "wordt gezocht in 'heading tags' (h1-h6). Standaard: %default" +# (pofilter) escapes: escapes in original ('"h\d,class,chapter".') don't match escapes in translation ('"h\d\klasse,hoofdstuk".') #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:165 msgid "" "Detect a chapter beginning at an element having the specified attribute. The " @@ -342,8 +343,8 @@ msgstr "" "vind het begin van een hoofdstuk bij een element met het gespecificeerde " "attribuut. Het formaat voor deze optie is tagnaam regexp, attribuut naam, " "attribuut waarde regexp. Bijvoorbeeld, om alle kop tags te vinden met de " -"attribuut klasse \"hoofstuk\", gebruik \"h\\d\\klasse,hoofdstuk\". Standaard " -"is %default" +"attribuut klasse \"hoofstuk\", gebruik \"h\\d,klasse,hoofdstuk\". Standaard is " +"%default" #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:167 msgid "" @@ -1307,10 +1308,11 @@ msgstr "Je hebt geen permissie om het bestand te lezen: " msgid "Error reading file" msgstr "Fout bij het lezen van bestand" +# (pofilter) xmltags: checks that XML/HTML tags have not been translated #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:183 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:53 msgid "

There was an error reading from file:
" -msgstr "

Er is een fout opgetreden bij het lezen van bestand:
" +msgstr "

Er is een fout opgetreden bij het lezen van bestand:
" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:189 msgid " is not a valid picture" @@ -1733,6 +1735,7 @@ msgid "Comma separated list of tags to remove from the books. " msgstr "" "Lijst van tags die moeten worden verwijderd, gescheiden met komma's. " +# (pofilter) xmltags: checks that XML/HTML tags have not been translated #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:235 msgid "" "

Enter your username and password for LibraryThing.com.
If you " @@ -1740,8 +1743,8 @@ msgid "" "for free!.

" msgstr "" "

Geef uw gebruikersnaam en wachtwoord voor LibraryThing.com. " -"
Als u deze niet heeft, dan kunt u er gratis een krijgen door te registreren" +"
Als u deze niet heeft, dan kunt u er gratis een krijgen door te registreren.

" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:265 msgid "Could not fetch cover.
" @@ -2181,26 +2184,29 @@ msgstr "Geen overeenkomst" msgid "Authors:" msgstr "Auteurs:" +# (pofilter) xmltags: checks that XML/HTML tags have not been translated #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:106 msgid "Regular expression group name (?P)" -msgstr "Reguliere expressie groep naam (?)" +msgstr "Reguliere expressie groep naam (?P)" #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:108 msgid "Series:" msgstr "Serie:" +# (pofilter) xmltags: checks that XML/HTML tags have not been translated #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:109 msgid "Regular expression group name (?P)" -msgstr "Reguliere expressie groep naam (?)" +msgstr "Reguliere expressie groep naam (?P)" #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:111 msgid "Series index:" msgstr "Serie Index" +# (pofilter) xmltags: checks that XML/HTML tags have not been translated #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:112 #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:115 msgid "Regular expression group name (?P)" -msgstr "Reguliere expressie groep naam (?)" +msgstr "Reguliere expressie groep naam (?P)" #: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:114 msgid "ISBN:" @@ -2825,13 +2831,14 @@ msgstr "FOUT: Niet-verwerkte uitzondering" msgid "Add a custom news source" msgstr "Voeg een persoonlijke nieuwsbron toe" +# (pofilter) xmltags: checks that XML/HTML tags have not been translated #: /home/kovid/work/calibre/src/calibre/gui2/news.py:53 msgid "" "

Please enter your username and password for %s
If you do not have one, " "please subscribe to get access to the articles.
Click OK to proceed." msgstr "" "

Voer uw gebruikersnaam en wachtwoord voor %s in.
Als u er geen geeft, " -"registreer dan om toegang tot de artikelen te krijgen.
Klik op OK om " +"registreer dan om toegang tot de artikelen te krijgen.
Klik op OK om " "verder te gaan." #: /home/kovid/work/calibre/src/calibre/gui2/news.py:79 @@ -3447,13 +3454,14 @@ msgstr "" "Maximum aantal level om recursief te zoeken -- de diepte om links te volgen. " "Standaard %default" +# (pofilter) xmltags: checks that XML/HTML tags have not been translated #: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:394 msgid "" "The maximum number of files to download. This only applies to files from tags. Default is %default" msgstr "" "Het maximum aantal bestanden te downloaden. Dit is alleen van toepassing op " -"bestanden in tags. Standaard is %default" +"bestanden in tags. Standaard is %default" #: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:396 msgid "" diff --git a/src/calibre/translations/ru.po b/src/calibre/translations/ru.po index d078b1d7d5..8e788d14d2 100644 --- a/src/calibre/translations/ru.po +++ b/src/calibre/translations/ru.po @@ -307,7 +307,9 @@ msgstr "" "Устанавливать разрывы страниц после тегов, имена которых соответствуют этому " "регулярному выражению." +# (pofilter) escapes: escapes in original ('"h\d,class,chapter".') don't match escapes in translation () #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 +#, fuzzy msgid "" "Force a page break before an element having the specified attribute. The " "format for this option is tagname regexp,attribute name,attribute value " From 3d94acb2713b4b4342bc6e0459f756d9448102a4 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 21 Jul 2008 20:44:38 -0700 Subject: [PATCH 03/34] Add --lit2oeb option to lit2lrf --- src/calibre/ebooks/lrf/lit/convert_from.py | 17 +++++++++++++++-- src/calibre/library/database.py | 2 +- src/calibre/translations/__init__.py | 14 ++++++++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/calibre/ebooks/lrf/lit/convert_from.py b/src/calibre/ebooks/lrf/lit/convert_from.py index 3d8a3f97b0..486a1e4cda 100644 --- a/src/calibre/ebooks/lrf/lit/convert_from.py +++ b/src/calibre/ebooks/lrf/lit/convert_from.py @@ -5,6 +5,7 @@ import os, sys, shutil, glob, logging from tempfile import mkdtemp from subprocess import Popen, PIPE from calibre.ebooks.lrf import option_parser as lrf_option_parser +from calibre.ebooks.lit.reader import LitReader from calibre.ebooks import ConversionError from calibre.ebooks.lrf.html.convert_from import process_file as html_process_file from calibre.ebooks.metadata.opf import OPFReader @@ -17,12 +18,24 @@ if islinux and getattr(sys, 'frozen_path', False): CLIT = os.path.join(getattr(sys, 'frozen_path'), 'clit') def option_parser(): - return lrf_option_parser( + parser = lrf_option_parser( _('''Usage: %prog [options] mybook.lit %prog converts mybook.lit to mybook.lrf''') ) + parser.add_option('--lit2oeb', default=False, dest='lit2oeb', action='store_true', + help='Use the new lit2oeb to convert lit files instead of convertlit.') + return parser + +def generate_html2(pathtolit, logger): + if not os.access(pathtolit, os.R_OK): + raise ConversionError, 'Cannot read from ' + pathtolit + tdir = mkdtemp(prefix=__appname__+'_') + lr = LitReader(pathtolit) + print 'Extracting LIT file to', tdir + lr.extract_content(tdir) + return tdir def generate_html(pathtolit, logger): if not os.access(pathtolit, os.R_OK): @@ -51,7 +64,7 @@ def process_file(path, options, logger=None): logger = logging.getLogger('lit2lrf') setup_cli_handlers(logger, level) lit = os.path.abspath(os.path.expanduser(path)) - tdir = generate_html(lit, logger) + tdir = generate_html2(lit, logger) if options.lit2oeb else generate_html(lit, logger) try: opf = glob.glob(os.path.join(tdir, '*.opf')) if opf: diff --git a/src/calibre/library/database.py b/src/calibre/library/database.py index d1f759e0f8..0a05f48dc9 100644 --- a/src/calibre/library/database.py +++ b/src/calibre/library/database.py @@ -778,7 +778,7 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE; isbn FROM books; ''') - conn.execute('pragma user_version=5') + conn.execute('pragma user_version=12') conn.commit() def __init__(self, dbpath, row_factory=False): diff --git a/src/calibre/translations/__init__.py b/src/calibre/translations/__init__.py index 01f546b42e..9aca9e9fca 100644 --- a/src/calibre/translations/__init__.py +++ b/src/calibre/translations/__init__.py @@ -70,8 +70,22 @@ def import_from_launchpad(url): open(out, 'wb').write(tf.extractfile(next).read()) next = tf.next() + check_for_critical_bugs() return 0 +def check_for_critical_bugs(): + if os.path.exists('.errors'): + shutil.rmtree('.errors') + pofilter = ('pofilter', '-i', '.', '-o', '.errors', + '-t', 'accelerators', '-t', 'escapes', '-t', 'variables', + '-t', 'xmltags') + subprocess.check_call(pofilter) + errs = os.listdir('.errors') + if errs: + print 'WARNING: Translation errors detected' + print 'See the .errors directory and http://translate.sourceforge.net/wiki/toolkit/using_pofilter' + + def main(args=sys.argv): if len(args) > 1: if args[1] == 'pot': From cff96e56a9406bb714379c46344f51e2e0712e63 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 21 Jul 2008 21:05:21 -0700 Subject: [PATCH 04/34] Fix #897 ('--line-spacing' option needed) --- src/calibre/ebooks/lrf/html/convert_from.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/ebooks/lrf/html/convert_from.py b/src/calibre/ebooks/lrf/html/convert_from.py index b118520b82..6533c6554b 100644 --- a/src/calibre/ebooks/lrf/html/convert_from.py +++ b/src/calibre/ebooks/lrf/html/convert_from.py @@ -1327,7 +1327,7 @@ class HTMLConverter(object, LoggingInterface): bls, ls = int(self.book.defaultTextStyle.attrs['baselineskip']), \ int(self.book.defaultTextStyle.attrs['linespace']) try: # See if line-height is a unitless number - val = int(float(tag_css['line-height'].strip()) * (bls+ls)) + val = int(float(tag_css['line-height'].strip()) * (ls)) fp['linespace'] = val except ValueError: val = self.unit_convert(tag_css['line-height'], pts=True, base_length='1pt') From e39ae6a88d5df141c5e4283f041df4fd58a0471d Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 22 Jul 2008 18:59:55 -0700 Subject: [PATCH 05/34] IGN:Rationalize build process --- .bzrignore | 3 + Makefile | 27 +- .../linux/freeze.py | 15 +- osx_installer.py => installer/osx/freeze.py | 110 ++-- installer/windows/calibre/calibre.mpi | 9 +- installer/windows/freeze.py | 60 +-- setup.py | 69 ++- src/calibre/__init__.py | 52 +- src/calibre/ebooks/lrf/lit/convert_from.py | 3 +- src/calibre/gui2/pictureflow/PyQt/Makefile | 46 -- .../gui2/pictureflow/PyQt/configure.py | 16 +- src/calibre/gui2/pictureflow/pictureflow.pro | 10 +- src/calibre/linux_installer.py | 10 +- src/calibre/translations/ru.po | 470 +++++++++--------- src/calibre/utils/lzx-setup.py | 5 - src/calibre/utils/lzx/setup.py | 15 - src/calibre/utils/winutil.c | 99 ++++ upload.py | 25 +- 18 files changed, 551 insertions(+), 493 deletions(-) rename linux_installer.py => installer/linux/freeze.py (91%) rename osx_installer.py => installer/osx/freeze.py (81%) delete mode 100644 src/calibre/gui2/pictureflow/PyQt/Makefile delete mode 100644 src/calibre/utils/lzx-setup.py delete mode 100644 src/calibre/utils/lzx/setup.py create mode 100644 src/calibre/utils/winutil.c diff --git a/.bzrignore b/.bzrignore index e27f39a864..37ab760e19 100644 --- a/.bzrignore +++ b/.bzrignore @@ -20,3 +20,6 @@ src/calibre/gui2/pictureflow/pictureflow_resource.rc src/calibre/gui2/pictureflow/release/ src/calibre/translations/compiled.py installer/windows/calibre/build.log +src/calibre/translations/.errors +src/calibre/plugins/* +src/calibre/gui2/pictureflow/.build diff --git a/Makefile b/Makefile index e2dc7770df..1990ad22bd 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,6 @@ PYTHON = python -all : plugins gui2 translations resources - -plugins : src/calibre/plugins pictureflow lzx - -src/calibre/plugins: - mkdir -p src/calibre/plugins +all : gui2 translations resources clean : cd src/calibre/gui2 && ${PYTHON} make.py clean @@ -25,26 +20,6 @@ resources: manual: make -C src/calibre/manual clean html -pictureflow : - mkdir -p src/calibre/plugins && rm -f src/calibre/plugins/*pictureflow* && \ - cd src/calibre/gui2/pictureflow && rm -f *.o && \ - mkdir -p .build && cd .build && rm -f * && \ - qmake ../pictureflow.pro && make staticlib && \ - cd ../PyQt && \ - mkdir -p .build && \ - cd .build && rm -f * && \ - ${PYTHON} ../configure.py && make && \ - cd ../../../../../.. && \ - cp src/calibre/gui2/pictureflow/PyQt/.build/pictureflow.so src/calibre/plugins/ && \ - rm -rf src/calibre/gui2/pictureflow/.build rm -rf src/calibre/gui2/pictureflow/PyQt/.build - -lzx : - mkdir -p src/calibre/plugins && rm -f src/calibre/plugins/lzx.so && \ - cd src/calibre/utils/lzx && \ - ${PYTHON} setup.py build --build-base=.build && cd - && \ - cp src/calibre/utils/lzx/.build/lib*/lzx.so src/calibre/plugins/ && \ - rm -rf src/calibre/utils/lzx/.build/ - pot : cd src/calibre/translations && ${PYTHON} __init__.py pot diff --git a/linux_installer.py b/installer/linux/freeze.py similarity index 91% rename from linux_installer.py rename to installer/linux/freeze.py index a1a0551afc..d79d3933d0 100644 --- a/linux_installer.py +++ b/installer/linux/freeze.py @@ -6,7 +6,7 @@ __docformat__ = 'restructuredtext en' ''' Create linux binary. ''' -import glob, sys, subprocess, tarfile, os, re, py_compile +import glob, sys, subprocess, tarfile, os, re, py_compile, shutil HOME = '/home/kovid' PYINSTALLER = os.path.expanduser('~/build/pyinstaller') CALIBREPREFIX = '___' @@ -33,7 +33,6 @@ open(os.path.join(PYINSTALLER, 'hooks', 'hook-calibre.parallel.py'), 'wb').write def run_pyinstaller(args=sys.argv): subprocess.check_call(('/usr/bin/sudo', 'chown', '-R', 'kovid:users', glob.glob('/usr/lib/python*/site-packages/')[-1])) subprocess.check_call('rm -rf %(py)s/dist/* %(py)s/build/*'%dict(py=PYINSTALLER), shell=True) - subprocess.check_call('make plugins', shell=True) cp = HOME+'/build/'+os.path.basename(os.getcwd()) spec = open(os.path.join(PYINSTALLER, 'calibre', 'calibre.spec'), 'wb') raw = re.sub(r'CALIBREPREFIX\s+=\s+\'___\'', 'CALIBREPREFIX = '+repr(cp), @@ -41,12 +40,14 @@ def run_pyinstaller(args=sys.argv): spec.write(raw) spec.close() os.chdir(PYINSTALLER) + shutil.rmtree('calibre/dist') + os.mkdir('calibre/dist') subprocess.check_call('python -OO Build.py calibre/calibre.spec', shell=True) return 0 -if __name__ == '__main__' and 'linux_installer.py' in __file__: +if __name__ == '__main__' and 'freeze.py' in __file__: sys.exit(run_pyinstaller()) @@ -59,7 +60,7 @@ os.chdir(os.environ.get("ORIGWD", ".")) sys.path.insert(0, os.path.join(sys.frozen_path, "library.pyz")) sys.path.insert(0, sys.frozen_path) from PyQt4.QtCore import QCoreApplication -QCoreApplication.setLibraryPaths([sys.frozen_path, os.path.join(sys.frozen_path, "plugins")]) +QCoreApplication.setLibraryPaths([sys.frozen_path, os.path.join(sys.frozen_path, "qtplugins")]) ''') excludes = ['gtk._gtk', 'gtk.glade', 'qt', 'matplotlib.nxutils', 'matplotlib._cntr', 'matplotlib.ttconv', 'matplotlib._image', 'matplotlib.ft2font', @@ -80,7 +81,7 @@ for entry in entry_points['console_scripts'] + entry_points['gui_scripts']: scripts.append(os.path.join(CALIBRESRC, *map(lambda x: x.strip(), fields[1].split(':')[0].split('.')))+'.py') analyses = [Analysis([os.path.join(HOMEPATH,'support/_mountzlib.py'), os.path.join(HOMEPATH,'support/useUnicode.py'), loader, script], - pathex=[PYINSTALLER, CALIBRESRC, CALIBREPLUGINS], excludes=excludes) for script in scripts] + pathex=[PYINSTALLER, CALIBRESRC], excludes=excludes) for script in scripts] pyz = TOC() binaries = TOC() @@ -104,6 +105,8 @@ for script, exe, a in zip(scripts, executables, analyses): print 'Adding plugins...' for f in glob.glob(os.path.join(CALIBREPLUGINS, '*.so')): + binaries += [('plugins/'+os.path.basename(f), f, 'BINARY')] +for f in glob.glob(os.path.join(CALIBREPLUGINS, '*.so.*')): binaries += [(os.path.basename(f), f, 'BINARY')] print 'Adding external programs...' @@ -121,7 +124,7 @@ for dirpath, dirnames, filenames in os.walk(plugdir): for f in filenames: if not f.endswith('.so') or 'designer' in dirpath or 'codcs' in dirpath or 'sqldrivers' in dirpath : continue f = os.path.join(dirpath, f) - plugins.append(('plugins/'+f.replace(plugdir, ''), f, 'BINARY')) + plugins.append(('qtplugins/'+f.replace(plugdir, ''), f, 'BINARY')) binaries += plugins manifest = '/tmp/manifest' diff --git a/osx_installer.py b/installer/osx/freeze.py similarity index 81% rename from osx_installer.py rename to installer/osx/freeze.py index c07702727d..ddef24075c 100644 --- a/osx_installer.py +++ b/installer/osx/freeze.py @@ -4,7 +4,14 @@ __copyright__ = '2008, Kovid Goyal ' ''' Create an OSX installer ''' import sys, re, os, shutil, subprocess, stat, glob, zipfile -from setup import VERSION, APPNAME, scripts, main_modules, basenames, main_functions +l = {} +exec open('setup.py').read() in l +VERSION = l['VERSION'] +APPNAME = l['APPNAME'] +scripts = l['scripts'] +basenames = l['basenames'] +main_functions = l['main_functions'] +main_modules = l['main_modules'] from setuptools import setup from py2app.build_app import py2app from modulegraph.find_modules import find_modules @@ -170,64 +177,46 @@ _check_symlinks_prescript() for f in files: subprocess.check_call(['/usr/bin/install_name_tool', '-change', '/Library/Frameworks/Python.framework/Versions/2.5/Python', '@executable_path/../Frameworks/Python.framework/Versions/2.5/Python', f]) + def fix_misc_dependencies(self, files): + for path in files: + frameworks_dir = os.path.join(self.dist_dir, APPNAME + '.app', 'Contents', 'Frameworks') + pipe = subprocess.Popen('/usr/bin/otool -L '+path, shell=True, stdout=subprocess.PIPE).stdout + for l in pipe.readlines(): + match = re.search(r'\s+(.*?)\s+\(', l) + if match: + dep = match.group(1) + name = os.path.basename(dep) + if not name: + name = dep + bundle = os.path.join(frameworks_dir, name) + if os.path.exists(bundle): + subprocess.check_call(['/usr/bin/install_name_tool', '-change', dep, + '@executable_path/../Frameworks/'+name, path]) + - def build_distutils_plugins(self): - plugins = [ - ('lzx', os.path.join('utils', 'lzx')), - ] - files = [] - env = {'PATH':os.environ['PATH']} - for name, path in plugins: - print 'Building plugin', name - path = os.path.abspath(os.path.join('src', 'calibre', path)) - cwd = os.getcwd() - os.chdir(path) - try: - if os.path.exists('.build'): - shutil.rmtree('.build') - subprocess.check_call((sys.executable, 'setup.py', 'build', '--build-base', '.build'), - env=env) - plugin = os.path.abspath(glob.glob('.build/lib*/%s.so'%name)[0]) - files.append([plugin, os.path.basename(plugin)]) - finally: - os.chdir(cwd) - return files - - def build_plugins(self): - cwd = os.getcwd() - qmake = '/Users/kovid/qt/bin/qmake' - files = [] - try: - print 'Building pictureflow' - os.chdir('src/calibre/gui2/pictureflow') - if not os.path.exists('.build'): - os.mkdir('.build') - os.chdir('.build') - for f in glob.glob('*'): os.unlink(f) - subprocess.check_call([qmake, '../pictureflow.pro']) - subprocess.check_call(['make']) - files.append((os.path.abspath(os.path.realpath('libpictureflow.dylib')), 'libpictureflow.dylib')) - os.chdir('../PyQt') - if not os.path.exists('.build'): - os.mkdir('.build') - os.chdir('.build') - for f in glob.glob('*'): os.unlink(f) - subprocess.check_call([PYTHON, '../configure.py']) - subprocess.check_call(['/usr/bin/make']) - files.append((os.path.abspath('pictureflow.so'), 'pictureflow.so')) - subprocess.check_call(['/usr/bin/install_name_tool', '-change', 'libpictureflow.0.dylib', '@executable_path/../Frameworks/libpictureflow.dylib', 'pictureflow.so']) - self.fix_python_dependencies((files[0][0], files[1][0])) - for i in range(2): - deps = BuildAPP.qt_dependencies(files[i][0]) - BuildAPP.fix_qt_dependencies(files[i][0], deps) - - return files - finally: - os.chdir(cwd) - + def add_plugins(self): + self.add_qt_plugins() + frameworks_dir = os.path.join(self.dist_dir, APPNAME + '.app', 'Contents', 'Frameworks') + plugins_dir = os.path.join(frameworks_dir, 'plugins') + if not os.path.exists(plugins_dir): + os.mkdir(plugins_dir) + + maps = {} + for f in glob.glob('src/calibre/plugins/*'): + tgt = plugins_dir + if f.endswith('.dylib'): + tgt = frameworks_dir + maps[f] = os.path.join(tgt, os.path.basename(f)) + deps = [] + for src, dst in maps.items(): + shutil.copyfile(src, dst) + self.fix_qt_dependencies(dst, self.qt_dependencies(dst)) + deps.append(dst) + self.fix_python_dependencies(deps) + self.fix_misc_dependencies(deps) + def run(self): - plugin_files = self.build_distutils_plugins() py2app.run(self) resource_dir = os.path.join(self.dist_dir, APPNAME + '.app', 'Contents', 'Resources') @@ -249,8 +238,8 @@ _check_symlinks_prescript() f.close() os.chmod(path, stat.S_IXUSR|stat.S_IXGRP|stat.S_IXOTH|stat.S_IREAD\ |stat.S_IWUSR|stat.S_IROTH|stat.S_IRGRP) - self.add_qt_plugins() - plugin_files += self.build_plugins() + self.add_plugins() + print print 'Adding clit' @@ -266,11 +255,6 @@ _check_symlinks_prescript() print 'Adding fontconfig' for f in glob.glob(os.path.expanduser('~/fontconfig2/*')): os.link(f, os.path.join(frameworks_dir, os.path.basename(f))) - for src, dest in plugin_files: - if 'dylib' in dest: - os.link(src, os.path.join(frameworks_dir, dest)) - else: - os.link(src, os.path.join(module_dir, dest)) dst = os.path.join(resource_dir, 'fonts') if os.path.exists(dst): shutil.rmtree(dst) diff --git a/installer/windows/calibre/calibre.mpi b/installer/windows/calibre/calibre.mpi index 6564c3183b..63d812f041 100644 --- a/installer/windows/calibre/calibre.mpi +++ b/installer/windows/calibre/calibre.mpi @@ -240,7 +240,6 @@ File ::B145A772-C20C-A6F2-E872-ACC229FFE1C7 -name fb2-meta.exe -parent 6CCF3F71- File ::168973D9-DEE6-7307-9A2E-746EB9456311 -name txt2lrf.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 File ::BD39D6F0-5125-F3A3-043F-E8FD1C87A823 -name isbndb.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 File ::6C294A11-52D4-C567-64F7-1DCF21AB06D7 -name epub2lrf.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::BBE8D78B-6646-5327-563C-7F8EE5842D7B -name pictureflow.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 File ::A9BB9531-5BC4-92C1-F614-B84B93F8698F -name pywintypes25.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 File ::AA725BD8-5FFA-B426-733F-5A1264A30DA2 -name Qt.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 File ::B48D9BFD-326D-1C92-4D94-C17F9ACD9207 -name epub2lrf.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 @@ -264,7 +263,6 @@ File ::2AABAB06-38EF-6F8C-3675-575D8B044E0C -name calibredb.exe -parent 6CCF3F71 File ::A7EA318A-0542-FBB8-5C93-A39B364A51D9 -name epub-meta.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 File ::4CD878C5-1487-1FFD-99A1-EDFC90892F0A -name win32security.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 File ::ADFDF202-EED8-0319-0D69-DF1C44AE465B -name librarything.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::B522E7CC-3C9B-325B-B0BA-3CAFD0228B6D -name pictureflow0.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 File ::0E83E956-FF8D-27AB-9BE9-A24C57F8886A -name pythoncom25.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 File ::F8DAAE4E-9BF0-F75A-78BD-81E0F4BD1F99 -name epub-meta.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 File ::E2982BD3-D0BB-70B4-0BF8-18B2B68C9918 -name QtWebKit4.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 @@ -351,6 +349,13 @@ File ::92701E8F-1D91-A796-C899-2A266029F61D -name _socket.pyd -parent 6CCF3F71-7 File ::45BD27B5-B910-7633-C827-37E82E89C27C -name w9xpopen.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 File ::45C27909-D761-787F-84B2-66596E5C4E99 -name bz2.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 File ::7B2DE5D8-17A6-B167-ABC7-799AEBCC1C02 -name clit.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 +File ::36E8EEAC-F54D-5DE9-02D8-ECDFEBB4B5E2 -type dir -name plugins -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 +File ::71930E14-A27B-C23C-8D94-C7E97ADB8723 -name pictureflow.pyd -parent 36E8EEAC-F54D-5DE9-02D8-ECDFEBB4B5E2 +File ::293E6ABE-17C9-5E53-1B44-C27029C8C061 -name winutil.pyd -parent 36E8EEAC-F54D-5DE9-02D8-ECDFEBB4B5E2 +File ::A5737158-18DF-7F20-2BDF-2DF615663891 -name lzx.pyd -parent 36E8EEAC-F54D-5DE9-02D8-ECDFEBB4B5E2 +File ::87085EC3-26D5-975D-A820-0691F193733D -name pictureflow1.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 +File ::CA9E098C-2931-9781-1303-213C242F9A5E -name lit2oeb.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 +File ::16B5A447-066C-C93E-F63D-8BC0D57CA544 -name lit2oeb.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 Component ::F6829AB7-9F66-4CEE-CA0E-21F54C6D3609 -setup Install -active Yes -platforms {AIX-ppc FreeBSD-4-x86 FreeBSD-x86 HPUX-hppa Linux-x86 Solaris-sparc Windows} -name Main -parent Components SetupType ::D9ADE41C-B744-690C-2CED-CF826BF03D2E -setup Install -active Yes -platforms {AIX-ppc FreeBSD-4-x86 FreeBSD-x86 HPUX-hppa Linux-x86 Solaris-sparc Windows} -name Typical -parent SetupTypes diff --git a/installer/windows/freeze.py b/installer/windows/freeze.py index 576ea5c5a9..4474776dc3 100644 --- a/installer/windows/freeze.py +++ b/installer/windows/freeze.py @@ -50,58 +50,16 @@ class BuildEXE(py2exe.build_exe.py2exe): ''' - def build_distutil_plugins(self): - plugins = [ - ('lzx', os.path.join('utils', 'lzx')), - ] - for name, path in plugins: - print 'Building plugin', name - path = os.path.abspath(os.path.join('src', 'calibre', path)) - cwd = os.getcwd() - dd = os.path.join(cwd, self.dist_dir) - os.chdir(path) - try: - if os.path.exists('.build'): - shutil.rmtree('.build') - subprocess.check_call(('python', 'setup.py', 'build', '--build-base', '.build')) - plugin = os.path.abspath(glob.glob('.build\\lib*\\%s.pyd'%name)[0]) - shutil.copyfile(plugin, os.path.join(dd, os.path.basename(plugin))) - finally: - os.chdir(cwd) - - def build_plugins(self): - cwd = os.getcwd() - dd = os.path.join(cwd, self.dist_dir) - try: - os.chdir(os.path.join('src', 'calibre', 'gui2', 'pictureflow')) - if os.path.exists('.build'): - shutil.rmtree('.build') - os.mkdir('.build') - os.chdir('.build') - subprocess.check_call(['qmake', '../pictureflow.pro']) - subprocess.check_call(['mingw32-make', '-f', 'Makefile.Release']) - shutil.copyfile('release\\pictureflow0.dll', os.path.join(dd, 'pictureflow0.dll')) - os.chdir('..\\PyQt') - if not os.path.exists('.build'): - os.mkdir('.build') - os.chdir('.build') - subprocess.check_call(['python', '..\\configure.py']) - subprocess.check_call(['mingw32-make', '-f', 'Makefile']) - shutil.copyfile('pictureflow.pyd', os.path.join(dd, 'pictureflow.pyd')) - os.chdir('..') - shutil.rmtree('.build', True) - os.chdir('..') - shutil.rmtree('.build', True) - finally: - os.chdir(cwd) - def run(self): - if not os.path.exists(self.dist_dir): - os.makedirs(self.dist_dir) - print 'Building custom plugins...' - self.build_distutil_plugins() - self.build_plugins() py2exe.build_exe.py2exe.run(self) + print 'Adding plugins...' + tgt = os.path.join(self.dist_dir, 'plugins') + if not os.path.exists(tgt): + os.mkdir(tgt) + for f in glob.glob(os.path.join(BASE_DIR, 'src', 'calibre', 'plugins', '*.dll')): + 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))) qtsvgdll = None for other in self.other_depends: if 'qtsvg4.dll' in other.lower(): @@ -116,7 +74,7 @@ class BuildEXE(py2exe.build_exe.py2exe): print 'Adding', qtxmldll shutil.copyfile(qtxmldll, os.path.join(self.dist_dir, os.path.basename(qtxmldll))) - print 'Adding plugins...', + print 'Adding Qt plugins...', qt_prefix = QT_DIR if qtsvgdll: qt_prefix = os.path.dirname(os.path.dirname(qtsvgdll)) diff --git a/setup.py b/setup.py index dcbacb47c4..608ffeed26 100644 --- a/setup.py +++ b/setup.py @@ -4,7 +4,9 @@ __copyright__ = '2008, Kovid Goyal ' import sys, re, os, shutil sys.path.append('src') -islinux = not ('win32' in sys.platform or 'win64' in sys.platform or 'darwin' in sys.platform) +iswindows = re.search('win(32|64)', sys.platform) +isosx = 'darwin' in sys.platform +islinux = not isosx and not iswindows src = open('src/calibre/__init__.py', 'rb').read() VERSION = re.search(r'__version__\s+=\s+[\'"]([^\'"]+)[\'"]', src).group(1) APPNAME = re.search(r'__appname__\s+=\s+[\'"]([^\'"]+)[\'"]', src).group(1) @@ -44,10 +46,72 @@ main_functions = { } if __name__ == '__main__': - from setuptools import setup, find_packages + from setuptools import setup, find_packages, Extension import subprocess, glob entry_points['console_scripts'].append('calibre_postinstall = calibre.linux:post_install') + ext_modules = [Extension('calibre.plugins.lzx', + sources=['src/calibre/utils/lzx/lzxmodule.c', + 'src/calibre/utils/lzx/lzxd.c'], + include_dirs=['src/calibre/utils/lzx'])] + if iswindows: + ext_modules.append(Extension('calibre.plugins.winutil', + sources=['src/calibre/utils/winutil.c'], libraries=['shell32']) + ) + # Build PyQt extensions + for path in [(os.path.join('src', 'calibre', 'gui2', 'pictureflow'))]: + pro = glob.glob(os.path.join(path, '*.pro'))[0] + raw = open(pro).read() + base = qtplugin = re.search(r'TARGET\s*=\s*(.*)', raw).group(1) + ver = re.search(r'VERSION\s*=\s*(\d+)', raw).group(1) + cwd = os.getcwd() + os.chdir(os.path.dirname(pro)) + try: + if not os.path.exists('.build'): + os.mkdir('.build') + os.chdir('.build') + subprocess.check_call(( (os.path.expanduser('~/qt/bin/qmake') if isosx else 'qmake'), '..'+os.sep+os.path.basename(pro))) + subprocess.check_call(['mingw32-make' if iswindows else 'make']) + ext = '.dll' if iswindows else '.dylib' if isosx else '.so' + if iswindows: + pat = re.compile(qtplugin+ver+ext) + elif isosx: + pat = re.compile('lib'+qtplugin+'.'+ver+ext) + else: + pat = re.compile('lib'+qtplugin+ext+'.'+ver+'$') + if iswindows: + os.chdir('release') + qtplugin = None + + for f in glob.glob('*'+ext+'*'): + if pat.match(f): + qtplugin = os.path.realpath(os.path.abspath(f)) + f = os.path.join(cwd, 'src', 'calibre', 'plugins', f) + shutil.copyfile(qtplugin, f) + if islinux: + os.symlink(f, f.rpartition(ext)[0]+ext) + if isosx: + os.symlink(f, f.replace('.'+ver, '')) + break + os.chdir(os.path.join('..'+(os.sep+'..' if iswindows else ''), 'PyQt')) + if not os.path.exists('.build'): + os.mkdir('.build') + os.chdir('.build') + python = '/Library/Frameworks/Python.framework/Versions/Current/bin/python' if isosx else 'python' + subprocess.check_call([python, '..'+os.sep+'configure.py']) + subprocess.check_call(['mingw32-make' if iswindows else 'make']) + ext = '.pyd' if iswindows else '.so' + plugin = glob.glob(base+ext)[0] + shutil.copyfile(plugin, os.path.join(cwd, 'src', 'calibre', 'plugins', plugin)) + finally: + os.chdir(cwd) + if islinux or isosx: + for f in glob.glob(os.path.join('src', 'calibre', 'plugins', '*')): + try: + os.readlink(f) + os.unlink(f) + except: + continue setup( name=APPNAME, @@ -62,6 +126,7 @@ if __name__ == '__main__': entry_points = entry_points, zip_safe = False, options = { 'bdist_egg' : {'exclude_source_files': True,}, }, + ext_modules=ext_modules, description = ''' E-book management application. diff --git a/src/calibre/__init__.py b/src/calibre/__init__.py index 0a11a02705..1568dc8710 100644 --- a/src/calibre/__init__.py +++ b/src/calibre/__init__.py @@ -43,6 +43,39 @@ try: except: preferred_encoding = 'utf-8' +if getattr(sys, 'frozen', False): + if iswindows: + plugin_path = os.path.join(os.path.dirname(sys.executable), 'plugins') + elif isosx: + plugin_path = os.path.join(getattr(sys, 'frameworks_dir'), 'plugins') + elif islinux: + plugin_path = os.path.join(getattr(sys, 'frozen_path'), 'plugins') + sys.path.insert(0, plugin_path) +else: + import pkg_resources + plugins = getattr(pkg_resources, 'resource_filename')(__appname__, 'plugins') + sys.path.insert(0, plugins) + +if iswindows and getattr(sys, 'frozen', False): + sys.path.insert(1, os.path.dirname(sys.executable)) + + +plugins = {} +for plugin in ['pictureflow', 'lzx'] + (['winutil'] if iswindows else []): + try: + p, err = __import__(plugin), '' + except Exception, err: + p = None + err = str(err) + plugins[plugin] = (p, err) + +if iswindows: + winutil, winutilerror = plugins['winutil'] + if not winutil: + raise RuntimeError('Failed to load the winutil plugin: %s'%winutilerror) + sys.argv[1:] = winutil.argv()[1:] + + _abspath = os.path.abspath def my_abspath(path, encoding=sys.getfilesystemencoding()): ''' @@ -606,22 +639,3 @@ if isosx: exec 'from calibre.ebooks.lrf.fonts.liberation.'+font+' import font_data' open(os.path.join(fdir, font+'.ttf'), 'wb').write(font_data) -if islinux and not getattr(sys, 'frozen', False): - import pkg_resources - plugins = pkg_resources.resource_filename(__appname__, 'plugins') - sys.path.insert(1, plugins) - -if iswindows and getattr(sys, 'frozen', False): - sys.path.insert(1, os.path.dirname(sys.executable)) - - -plugins = {} -for plugin in ['pictureflow', 'lzx']: - try: - p, err = __import__(plugin), '' - except Exception, err: - p = None - err = str(err) - plugins[plugin] = (p, err) - - diff --git a/src/calibre/ebooks/lrf/lit/convert_from.py b/src/calibre/ebooks/lrf/lit/convert_from.py index 486a1e4cda..66d7b1182e 100644 --- a/src/calibre/ebooks/lrf/lit/convert_from.py +++ b/src/calibre/ebooks/lrf/lit/convert_from.py @@ -64,7 +64,8 @@ def process_file(path, options, logger=None): logger = logging.getLogger('lit2lrf') setup_cli_handlers(logger, level) lit = os.path.abspath(os.path.expanduser(path)) - tdir = generate_html2(lit, logger) if options.lit2oeb else generate_html(lit, logger) + tdir = generate_html2(lit, logger) if getattr(options, 'lit2oeb', False) \ + else generate_html(lit, logger) try: opf = glob.glob(os.path.join(tdir, '*.opf')) if opf: diff --git a/src/calibre/gui2/pictureflow/PyQt/Makefile b/src/calibre/gui2/pictureflow/PyQt/Makefile deleted file mode 100644 index f22d6515c6..0000000000 --- a/src/calibre/gui2/pictureflow/PyQt/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -TARGET = pictureflow.so -OFILES = sippictureflowcmodule.o sippictureflowPictureFlow.o -HFILES = sipAPIpictureflow.h - -CC = gcc -CXX = g++ -LINK = g++ -CPPFLAGS = -DQT_NO_DEBUG -DQT_THREAD_SUPPORT -I. -I/usr/include/python2.5 -I/usr/lib/qt-3.3/mkspecs/default -I/usr/lib/qt-3.3/include -CFLAGS = -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables -fPIC -Wall -W -D_REENTRANT -CXXFLAGS = -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables -fPIC -Wall -W -D_REENTRANT -LFLAGS = -shared -Wl,--version-script=pictureflow.exp -LIBS = -L.. -L/usr/lib/qt-3.3/lib -lpictureflow -lqt-mt -lXext -lX11 -lm -lpthread -MOC = /usr/lib/qt-3.3/bin/moc -.SUFFIXES: .c .o .cpp .cc .cxx .C - - -.cpp.o: - $(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $@ $< - -.cc.o: - $(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $@ $< - -.cxx.o: - $(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $@ $< - -.C.o: - $(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $@ $< - -.c.o: - $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $< - -$(TARGET): $(OFILES) - @echo '{ global: initpictureflow; local: *; };' > pictureflow.exp - $(LINK) $(LFLAGS) -o $(TARGET) $(OFILES) $(LIBS) - -$(OFILES): $(HFILES) - -install: $(TARGET) - @test -d $(DESTDIR)/usr/lib/python2.5/site-packages || mkdir -p $(DESTDIR)/usr/lib/python2.5/site-packages - cp -f $(TARGET) $(DESTDIR)/usr/lib/python2.5/site-packages/$(TARGET) - -clean: - -rm -f $(TARGET) - -rm -f sippictureflowcmodule.o - -rm -f sippictureflowPictureFlow.o - -rm -f pictureflow.exp diff --git a/src/calibre/gui2/pictureflow/PyQt/configure.py b/src/calibre/gui2/pictureflow/PyQt/configure.py index 8b6295d817..61115f5fa6 100644 --- a/src/calibre/gui2/pictureflow/PyQt/configure.py +++ b/src/calibre/gui2/pictureflow/PyQt/configure.py @@ -1,4 +1,4 @@ -import os, sys, glob, shutil +import os, sys import sipconfig if os.environ.get('PYQT4PATH', None): print os.environ['PYQT4PATH'] @@ -35,16 +35,14 @@ makefile = pyqtconfig.QtGuiModuleMakefile ( # Add the library we are wrapping. The name doesn't include any platform # specific prefixes or extensions (e.g. the "lib" prefix on UNIX, or the # ".dll" extension on Windows). -if 'linux' in sys.platform: - for f in glob.glob('../../.build/libpictureflow.a'): - shutil.copyfile(f, os.path.basename(f)) - makefile.extra_lib_dirs = ['.'] -else: - makefile.extra_lib_dirs = ['..\\..\\.build\\release', '../../.build', '.'] -makefile.extra_libs = ['pictureflow0' if 'win' in sys.platform and 'darwin' not in sys.platform else "pictureflow"] +d = os.path.dirname +makefile.extra_lib_dirs += [os.path.abspath(os.path.join(d(d(d(d(os.getcwd())))), 'plugins')).replace(os.sep, '/')] +makefile.extra_libs += ['pictureflow1' if 'win32' in sys.platform else 'pictureflow'] makefile.extra_cflags = ['-arch i386', '-arch ppc'] if 'darwin' in sys.platform else [] makefile.extra_lflags = ['-arch i386', '-arch ppc'] if 'darwin' in sys.platform else [] makefile.extra_cxxflags = makefile.extra_cflags +if 'win32' in sys.platform: + makefile.extra_lib_dirs += ['C:/Python25/libs'] # Generate the Makefile itself. makefile.generate() @@ -60,6 +58,6 @@ content = { # This creates the helloconfig.py module from the helloconfig.py.in # template and the dictionary. -sipconfig.create_config_module("pictureflowconfig.py", "../pictureflowconfig.py.in", content) +sipconfig.create_config_module("pictureflowconfig.py", '..'+os.sep+'pictureflowconfig.py.in', content) diff --git a/src/calibre/gui2/pictureflow/pictureflow.pro b/src/calibre/gui2/pictureflow/pictureflow.pro index 6632b7eede..a299ab9ce1 100644 --- a/src/calibre/gui2/pictureflow/pictureflow.pro +++ b/src/calibre/gui2/pictureflow/pictureflow.pro @@ -1,6 +1,6 @@ -TARGET = pictureflow +TARGET = pictureflow TEMPLATE = lib -HEADERS = pictureflow.h -SOURCES = pictureflow.cpp -VERSION = 0.2.0 -CONFIG += x86 ppc +HEADERS = pictureflow.h +SOURCES = pictureflow.cpp +VERSION = 1.0.0 +CONFIG += x86 ppc diff --git a/src/calibre/linux_installer.py b/src/calibre/linux_installer.py index d2266720f9..b433c36ffc 100644 --- a/src/calibre/linux_installer.py +++ b/src/calibre/linux_installer.py @@ -251,8 +251,14 @@ def download_tarball(): except ValueError: print 'Downloading calibre...' pb = None - src = urllib2.urlopen(MOBILEREAD+'calibre-%version-i686.tar.bz2') - size = int(src.info()['content-length']) + local = 'calibre-test.tar.bz2' + src = open(local) if os.access(local, os.R_OK) else urllib2.urlopen(MOBILEREAD+'calibre-%version-i686.tar.bz2') + if hasattr(src, 'info'): + size = int(src.info()['content-length']) + else: + src.seek(0, 2) + size = src.tell() + src.seek(0) f = tempfile.NamedTemporaryFile() while f.tell() < size: f.write(src.read(4*1024)) diff --git a/src/calibre/translations/ru.po b/src/calibre/translations/ru.po index 8e788d14d2..b0277eed95 100644 --- a/src/calibre/translations/ru.po +++ b/src/calibre/translations/ru.po @@ -6,23 +6,23 @@ msgid "" msgstr "" "Project-Id-Version: calibre 0.4.55\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-07-09 04:18+0000\n" -"PO-Revision-Date: 2008-07-02 21:26+0000\n" -"Last-Translator: Danil Semelenov \n" +"POT-Creation-Date: 2008-07-21 22:18+0000\n" +"PO-Revision-Date: 2008-07-22 05:27+0000\n" +"Last-Translator: Kovid Goyal \n" "Language-Team: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2008-07-19 02:36+0000\n" +"X-Launchpad-Export-Date: 2008-07-22 05:44+0000\n" "X-Generator: Launchpad (build Unknown)\n" "Generated-By: pygettext.py 1.5\n" -#: /home/kovid/work/calibre/src/calibre/__init__.py:133 +#: /home/kovid/work/calibre/src/calibre/__init__.py:138 #, fuzzy msgid "%sUsage%s: %s\n" msgstr "%sИспользовано%s: %s\n" -#: /home/kovid/work/calibre/src/calibre/__init__.py:170 +#: /home/kovid/work/calibre/src/calibre/__init__.py:175 msgid "Created by " msgstr "Сделано " @@ -55,9 +55,9 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:429 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:685 -#: /home/kovid/work/calibre/src/calibre/library/database.py:925 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1433 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1563 +#: /home/kovid/work/calibre/src/calibre/library/database.py:879 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1387 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1517 msgid "Unknown" msgstr "Неизвестно" @@ -307,16 +307,13 @@ msgstr "" "Устанавливать разрывы страниц после тегов, имена которых соответствуют этому " "регулярному выражению." -# (pofilter) escapes: escapes in original ('"h\d,class,chapter".') don't match escapes in translation () #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 -#, fuzzy msgid "" "Force a page break before an element having the specified attribute. The " "format for this option is tagname regexp,attribute name,attribute value " "regexp. For example to match all heading tags that have the attribute " "class=\"chapter\" you would use \"h\\d,class,chapter\". Default is %default" msgstr "" -"Устанавливать разрывы страниц до элементов, имеющих определенный атрибут." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:182 msgid "Add detected chapters to the table of contents." @@ -394,7 +391,7 @@ msgstr "" "распространенный вариант — utf-8. По умолчанию будет сделана попытка угадать " "кодировку." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:144 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:146 msgid "" "any2lrf [options] myfile\n" "\n" @@ -413,7 +410,7 @@ msgstr "" "ZIP, пытаясь обнаружить электронную книгу в архиве.\n" " " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:159 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:161 msgid "No file to convert specified." msgstr "Не указан файл для преобразования." @@ -429,7 +426,7 @@ msgstr "" "\n" "%prog преобразует mybook.epub в mybook.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:19 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:17 msgid "" "%prog [options] mybook.fb2\n" "\n" @@ -441,11 +438,15 @@ msgstr "" "\n" "%prog преобразует mybook.fb2 в mybook.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:24 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:22 #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:22 msgid "Print generated HTML to stdout and quit." msgstr "Распечатать сгенерированный HTML в stdout и выйти." +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:24 +msgid "Keep generated HTML files after completing conversion to LRF." +msgstr "" + #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:22 msgid "Options to control the behavior of feeds2disk" msgstr "Опции управления поведением feeds2disk" @@ -458,96 +459,96 @@ msgstr "Опции управления поведением html2lrf" msgid "Fetching of recipe failed: " msgstr "Скачивание подпорки не удалось: " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:315 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:316 msgid "\tBook Designer file detected." msgstr "\tОпределен файл в формате Book Designer." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:317 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:318 msgid "\tParsing HTML..." msgstr "\tРазбор HTML..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:339 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:340 msgid "\tBaen file detected. Re-parsing..." msgstr "\tОпределен файл в формате Baen. Повторный разбор..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:355 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:356 #, fuzzy msgid "Written preprocessed HTML to " msgstr "Предварительно обработанный HTML сохранен в " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:373 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:374 msgid "Processing %s" msgstr "Обработка %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:387 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:388 msgid "\tConverting to BBeB..." msgstr "\tПреобразование в BBeB..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:530 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:543 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:531 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:544 msgid "Could not parse file: %s" msgstr "Не удалось разобрать файл: %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:535 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:536 msgid "%s is an empty file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:555 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:556 msgid "Failed to parse link %s %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:599 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:600 msgid "Cannot add link %s to TOC" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:944 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:949 msgid "Unable to process image %s. Error: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:982 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:987 msgid "Unable to process interlaced PNG %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:997 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1002 msgid "" "Could not process image: %s\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1744 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1749 msgid "" "An error occurred while processing a table: %s. Ignoring table markup." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1746 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1751 msgid "" "Bad table:\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1768 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1773 msgid "Table has cell that is too large" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1798 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1803 msgid "" "You have to save the website %s as an html file first and then run html2lrf " "on it." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1841 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1846 msgid "Could not read cover image: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1844 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1849 msgid "Cannot read from: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1978 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1984 msgid "Failed to process opf file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1984 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1990 msgid "" "Usage: %prog [options] mybook.html\n" "\n" @@ -745,7 +746,7 @@ msgid "mybook.epub" msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:100 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:34 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:50 msgid "Usage:" msgstr "" @@ -818,19 +819,19 @@ msgstr "" msgid "No filename specified." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:344 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:391 msgid "%prog [options] myebook.mobi" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:346 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:393 msgid "Output directory. Defaults to current directory." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:365 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:412 msgid "Raw MOBI HTML saved in" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:367 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:414 msgid "OEB ebook created in" msgstr "" @@ -847,7 +848,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:27 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:58 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:531 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:20 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:246 msgid "Comments" @@ -876,52 +877,53 @@ msgstr "" msgid "Advanced" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:104 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:105 msgid "
Must be a directory." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:104 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:105 msgid "Invalid database location " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:104 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:105 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:108 msgid "Invalid database location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:108 msgid "Invalid database location.
Cannot write to " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:120 msgid "Compacting database. This may take a while." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:120 msgid "Compacting..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:206 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:216 #: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:265 msgid "Configuration" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:207 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:217 msgid "&Location of books database (library1.db)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:208 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:218 msgid "Browse for the new database location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:209 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:226 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:219 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:513 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:278 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:266 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:296 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:126 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:128 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:131 @@ -935,85 +937,89 @@ msgstr "" msgid "..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:210 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:220 msgid "Use &Roman numerals for series number" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:211 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:221 +msgid "&Number of covers to show in browse mode (after restart):" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:222 msgid "Show notification when &new version is available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:212 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:223 msgid "Format for &single file save:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:213 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:224 msgid "&Priority for conversion jobs:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:214 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:225 msgid "Default network &timeout:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:215 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:226 msgid "" "Set the default timeout for network fetches (i.e. anytime we go out to the " "internet to get information)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:216 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:227 msgid " seconds" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:217 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:228 msgid "Toolbar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:218 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:229 msgid "Large" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:219 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:230 msgid "Medium" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:220 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:231 msgid "Small" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:232 msgid "&Button size in toolbar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:222 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:233 msgid "Show &text in toolbar buttons" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:223 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 msgid "Select visible &columns in library view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:224 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 msgid "Frequently used directories" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:225 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:236 msgid "Add a directory to the frequently used directories list" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 msgid "Remove a directory from the frequently used directories list" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:229 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 msgid "Free unused diskspace from the database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 msgid "&Compact database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 msgid "&Metadata from file name" msgstr "" @@ -1145,7 +1151,7 @@ msgid "Convert %s to LRF" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:108 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:177 msgid "Set conversion defaults" msgstr "" @@ -1236,17 +1242,17 @@ msgid "Options" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 msgid "Book Cover" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:291 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:298 msgid "Change &cover image:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:292 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 msgid "Browse for an image to use as the cover of this book." msgstr "" @@ -1255,25 +1261,25 @@ msgid "Use cover from &source file" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:515 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:258 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:263 msgid "&Title: " msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:516 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:259 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:264 msgid "Change the title of this book" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:260 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:267 msgid "&Author(s): " msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:268 msgid "" "Change the author(s) of this book. Multiple authors should be separated by a " "comma" @@ -1285,24 +1291,24 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:268 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 msgid "&Publisher: " msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:269 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 msgid "Change the publisher of this book" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 msgid "Ta&gs: " msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:524 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:127 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:278 msgid "" "Tags categorize the book. This is particularly useful while searching. " "

They can be any words or phrases, separated by commas." @@ -1310,7 +1316,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:525 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:132 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:281 msgid "&Series:" msgstr "" @@ -1318,20 +1324,20 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:527 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:133 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:134 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:282 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 msgid "List of known series. You can add new series." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:528 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:529 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 msgid "Series index." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 msgid "Book " msgstr "" @@ -1507,36 +1513,36 @@ msgid "Edit Meta information" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:257 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:262 msgid "Meta information" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:118 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:269 msgid "Author S&ort: " msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:119 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:270 msgid "" "Specify how the author(s) of this book should be sorted. For example Charles " "Dickens should be sorted as Dickens, Charles." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:120 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:264 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:271 msgid "&Rating:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:121 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:265 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:266 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:272 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 msgid "Rating of this book. 0-5 stars" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:123 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:267 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 msgid " stars" msgstr "" @@ -1546,8 +1552,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:128 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:129 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:272 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 msgid "Open Tag Editor" msgstr "" @@ -1559,67 +1565,71 @@ msgstr "" msgid "Comma separated list of tags to remove from the books. " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:241 msgid "" "

Enter your username and password for LibraryThing.com.
If you " "do not have one, you can
register " "for free!.

" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 msgid "Could not fetch cover.
" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 msgid "Could not fetch cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 msgid "Cannot fetch cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 msgid "You must specify the ISBN identifier for this book." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:256 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:261 msgid "Edit Meta Information" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 -msgid "Remove unused series (Series that have no books)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:282 -msgid "IS&BN:" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:265 +msgid "Swap the author and title" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +msgid "Remove unused series (Series that have no books)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +msgid "IS&BN:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:291 msgid "Fetch metadata from server" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:292 msgid "Available Formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 msgid "Add a new format for this book to the database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:295 msgid "Remove the selected formats for this book from the database." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 msgid "Fetch cover image from server" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:295 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 msgid "" "Change the username and/or password for your account at LibraryThing.com" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:296 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:303 msgid "Change password" msgstr "" @@ -2164,110 +2174,110 @@ msgstr "" msgid "Configure" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:82 msgid "Error communicating with device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:93 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:95 msgid "" "

For help visit %s.kovidgoyal.net
" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:94 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:96 msgid "%s: %s by Kovid Goyal %%(version)s
%%(device)s

" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:112 #: /home/kovid/work/calibre/src/calibre/gui2/main.py:114 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 msgid "Send to main memory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:113 #: /home/kovid/work/calibre/src/calibre/gui2/main.py:115 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 msgid "Send to storage card" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:114 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:115 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 msgid "and delete from library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 msgid "Send to storage card by default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:129 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:131 msgid "Edit metadata individually" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:130 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:132 msgid "Edit metadata in bulk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:133 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 msgid "Add books from a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:134 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 msgid "" "Add books recursively (One book per directory, assumes every ebook file is " "the same book in a different format)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:137 msgid "" "Add books recursively (Multiple books per directory, assumes every ebook " "file is a different book)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:150 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:152 #: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 msgid "Save to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:151 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:153 msgid "Save to disk in a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:152 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:154 msgid "Save only %s format to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:155 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 #: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 msgid "View" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:156 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 msgid "View specific format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:172 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:174 msgid "Convert individually" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:173 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:175 msgid "Bulk convert" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:307 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:309 msgid " detected." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:307 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:309 msgid "Device: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:332 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:334 msgid "Connected " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:344 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:346 msgid "Device database corrupted" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:345 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:347 msgid "" "\n" "

The database of books on the reader is corrupted. Try the " @@ -2283,190 +2293,190 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:397 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:471 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:399 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:473 msgid "" "

Books with the same title as the following already exist in the database. " "Add them anyway?

    " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:400 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:474 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:402 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:476 msgid "Duplicates found!" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:433 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:446 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:435 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:448 msgid "Uploading books to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:505 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:507 msgid "No space on device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:506 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:508 msgid "" "

    Cannot upload books to device there is no more free space available " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:544 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:546 msgid "Deleting books from device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:576 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:597 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:578 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:599 msgid "Cannot edit metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:576 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:597 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:692 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:762 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:832 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:578 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:599 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:694 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:764 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:834 msgid "No books selected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:672 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:674 msgid "Sending books to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:675 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:677 msgid "No suitable formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:676 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:678 msgid "" "Could not upload the following books to the device, as no suitable formats " "were found:

      %s
    " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:692 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:694 msgid "Cannot save to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:703 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:705 msgid "" "

    Could not save the following books to disk, because the %s format is not " "available for them:

      " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:707 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:709 msgid "Could not save some ebooks" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:740 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:742 msgid "Fetch news from " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:742 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:744 msgid "Fetching news from " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:752 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:754 msgid "News fetched. Uploading to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:762 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:832 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:764 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:834 msgid "Cannot convert" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:771 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:773 msgid "Starting Bulk conversion of %d books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:903 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:921 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:905 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:923 msgid "No book selected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:903 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:921 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:935 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:905 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:923 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:937 msgid "Cannot view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:909 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:940 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:911 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:942 msgid "Choose the format to view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:936 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:938 msgid "%s has no available formats." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:974 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:976 msgid "Cannot configure" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:974 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:976 msgid "Cannot configure while there are running jobs." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:997 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:999 msgid "Copying database to " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1012 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1014 msgid "Invalid database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1013 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1015 msgid "" "

      An invalid database already exists at %s, delete it before trying to move " "the existing database.
      Error: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1021 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1023 msgid "Could not move database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1042 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1044 msgid "No detailed info available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1043 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1045 msgid "No detailed information is available for books on the device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1085 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1087 msgid "Error talking to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1086 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1088 msgid "" "There was a temporary error talking to the device. Please unplug and " "reconnect the device and or reboot." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1137 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1139 msgid "Conversion Error" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1156 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1158 msgid "Database does not exist" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1156 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1158 msgid "" "The directory in which the database should be: %s no longer exists. Please " "choose a new database location." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1207 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1209 msgid "" "Latest version: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1213 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1215 msgid "" "%s has been updated to version %s. See the new features. " "Visit the download page?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1213 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1215 msgid "Update available" msgstr "" @@ -2684,13 +2694,13 @@ msgstr "" msgid "Invalid sort field. Available fields:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:173 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:174 msgid "" "The following books were not added as they already exist in the database " "(see --duplicates option):" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:197 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:198 msgid "" "%prog add [options] file1 file2 file3 ...\n" "\n" @@ -2699,27 +2709,27 @@ msgid "" "the directory related options below. \n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:206 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:207 msgid "" "Assume that each directory has only a single logical book and that all files " "in it are different e-book formats of that book" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:208 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:209 msgid "Process directories recursively" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:210 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:211 msgid "" "Add books to database even if they already exist. Comparison is done based " "on book titles." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:215 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:216 msgid "You must specify at least one file to add" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:233 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:234 msgid "" "%prog remove ids\n" "\n" @@ -2728,11 +2738,11 @@ msgid "" "command). For example, 23,34,57-85\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:245 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:246 msgid "You must specify at least one book to remove" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:265 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:266 msgid "" "%prog add_format [options] id ebook_file\n" "\n" @@ -2741,15 +2751,15 @@ msgid "" "already exists, it is replaced.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:276 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:277 msgid "You must specify an id and an ebook file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:281 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:282 msgid "ebook file must have an extension" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:289 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:290 msgid "" "\n" "%prog remove_format [options] id fmt\n" @@ -2759,11 +2769,11 @@ msgid "" "EPUB. If the logical book does not have fmt available, do nothing.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:302 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:303 msgid "You must specify an id and a format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:320 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:321 msgid "" "\n" "%prog show_metadata [options] id\n" @@ -2773,15 +2783,15 @@ msgid "" "id is an id number from the list command. \n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:328 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:329 msgid "Print metadata in OPF form (XML)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:333 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:334 msgid "You must specify an id" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:347 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:348 msgid "" "\n" "%prog set_metadata [options] id /path/to/metadata.opf\n" @@ -2794,11 +2804,11 @@ msgid "" "show_metadata command.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:360 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:361 msgid "You must specify an id and a metadata file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:372 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:373 msgid "" "%prog export [options] ids \n" "\n" @@ -2809,27 +2819,27 @@ msgid "" "an opf file). You can get id numbers from the list command. \n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:380 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:381 msgid "Export all books in database, ignoring the list of ids." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:382 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:383 msgid "Export books to the specified directory. Default is" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:384 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:385 msgid "Export all books into a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:386 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:387 msgid "Create file names as author - title instead of title - author" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:391 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:392 msgid "You must specify some ids or the %s option" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:401 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:402 msgid "" "%%prog command [options] [arguments]\n" "\n" @@ -2841,11 +2851,11 @@ msgid "" "For help on an individual command: %%prog command --help\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/parallel.py:321 +#: /home/kovid/work/calibre/src/calibre/parallel.py:344 msgid "Could not launch worker process." msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/fontconfig.py:146 +#: /home/kovid/work/calibre/src/calibre/utils/fontconfig.py:157 msgid "Could not initialize the fontconfig library" msgstr "" diff --git a/src/calibre/utils/lzx-setup.py b/src/calibre/utils/lzx-setup.py deleted file mode 100644 index 87e523b9c3..0000000000 --- a/src/calibre/utils/lzx-setup.py +++ /dev/null @@ -1,5 +0,0 @@ -from distutils.core import setup, Extension - -setup(name="lzx", version="1.0", - ext_modules=[Extension('lzx', sources=['lzx/lzxmodule.c', 'lzx/lzxd.c'], - include_dirs=['lzx'])]) diff --git a/src/calibre/utils/lzx/setup.py b/src/calibre/utils/lzx/setup.py deleted file mode 100644 index 62fb37b12c..0000000000 --- a/src/calibre/utils/lzx/setup.py +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env python -__license__ = 'GPL v3' -__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' -__docformat__ = 'restructuredtext en' - -''' -Build the lzx decompressor extension -''' -from distutils.core import setup, Extension - -setup(name="lzx", version="1.0", - ext_modules=[Extension('lzx', - sources=['lzxmodule.c', 'lzxd.c'], - include_dirs=['.'])]) - diff --git a/src/calibre/utils/winutil.c b/src/calibre/utils/winutil.c new file mode 100644 index 0000000000..04a4c3a49b --- /dev/null +++ b/src/calibre/utils/winutil.c @@ -0,0 +1,99 @@ +#define UNICODE +#include +#include +#include +#include + + +static PyObject * +winutil_folder_path(PyObject *self, PyObject *args) { + int res; DWORD dwFlags; + PyObject *ans = NULL; + TCHAR wbuf[MAX_PATH]; CHAR buf[4*MAX_PATH]; + memset(wbuf, 0, sizeof(TCHAR)*MAX_PATH); memset(buf, 0, sizeof(CHAR)*MAX_PATH); + + if (!PyArg_ParseTuple(args, "l", &dwFlags)) return NULL; + + res = SHGetFolderPath(NULL, dwFlags, NULL, 0, wbuf); + if (res != S_OK) { + if (res == E_FAIL) PyErr_SetString(PyExc_ValueError, "Folder does not exist."); + PyErr_SetString(PyExc_ValueError, "Folder not valid"); + return NULL; + } + res = WideCharToMultiByte(CP_UTF8, 0, wbuf, -1, buf, 4*MAX_PATH, NULL, NULL); + ans = PyUnicode_DecodeUTF8(buf, res-1, "strict"); + return ans; +} + +static PyObject * +winutil_argv(PyObject *self, PyObject *args) { + PyObject *argv, *v; + LPWSTR *_argv; + LPSTR buf; + int argc, i, bytes; + if (!PyArg_ParseTuple(args, "")) return NULL; + _argv = CommandLineToArgvW(GetCommandLine(), &argc); + if (_argv == NULL) { PyErr_SetString(PyExc_RuntimeError, "Out of memory."); return NULL; } + argv = PyList_New(argc); + if (argv != NULL) { + for (i = 0; i < argc; i++) { + bytes = WideCharToMultiByte(CP_UTF8, 0, _argv[i], -1, NULL, 0, NULL, NULL); + buf = (LPSTR)PyMem_Malloc(sizeof(CHAR)*bytes); + if (buf == NULL) { Py_DECREF(argv); argv = NULL; break; } + WideCharToMultiByte(CP_UTF8, 0, _argv[i], -1, buf, bytes, NULL, NULL); + v = PyUnicode_DecodeUTF8(buf, bytes-1, "strict"); + PyMem_Free(buf); + if (v == NULL) { Py_DECREF(argv); argv = NULL; break; } + PyList_SetItem(argv, i, v); + } + } + LocalFree(_argv); + return argv; +} + +static PyMethodDef WinutilMethods[] = { + {"folder_path", winutil_folder_path, METH_VARARGS, + "folder_path(csidl_id) -> path\n\n" + "Get paths to common system folders. " + "See windows documentation of SHGetFolderPath. " + "The paths are returned as unicode objects. csidl_id should be one " + "of the symbolic constants defined in this module. You can also OR " + "a symbolic constant with CSIDL_FLAG_CREATE to force the operating " + "system to create a folder if it does not exist."}, + {"argv", winutil_argv, METH_VARARGS, + "argv() -> list of command line arguments\n\n" + "Get command line arguments as unicode objects. Note that the " + "first argument will be the path to the interpreter, *not* the " + "script being run. So to replace sys.argv, you should use " + "sys.argv[1:] = argv()[1:]."}, + + {NULL, NULL, 0, NULL} +}; + +PyMODINIT_FUNC +initwinutil(void) { + PyObject *m; + m = Py_InitModule3("winutil", WinutilMethods, + "Defines utility methods to interface with windows." + ); + if (m == NULL) return; + PyModule_AddIntConstant(m, "CSIDL_ADMINTOOLS", CSIDL_ADMINTOOLS); + PyModule_AddIntConstant(m, "CSIDL_APPDATA", CSIDL_APPDATA); + PyModule_AddIntConstant(m, "CSIDL_COMMON_ADMINTOOLS", CSIDL_COMMON_ADMINTOOLS); + PyModule_AddIntConstant(m, "CSIDL_COMMON_APPDATA", CSIDL_COMMON_APPDATA); + PyModule_AddIntConstant(m, "CSIDL_COMMON_DOCUMENTS", CSIDL_COMMON_DOCUMENTS); + PyModule_AddIntConstant(m, "CSIDL_COOKIES", CSIDL_COOKIES); + PyModule_AddIntConstant(m, "CSIDL_FLAG_CREATE", CSIDL_FLAG_CREATE); + PyModule_AddIntConstant(m, "CSIDL_FLAG_DONT_VERIFY", CSIDL_FLAG_DONT_VERIFY); + PyModule_AddIntConstant(m, "CSIDL_HISTORY", CSIDL_HISTORY); + PyModule_AddIntConstant(m, "CSIDL_INTERNET_CACHE", CSIDL_INTERNET_CACHE); + PyModule_AddIntConstant(m, "CSIDL_LOCAL_APPDATA", CSIDL_LOCAL_APPDATA); + PyModule_AddIntConstant(m, "CSIDL_MYPICTURES", CSIDL_MYPICTURES); + PyModule_AddIntConstant(m, "CSIDL_PERSONAL", CSIDL_PERSONAL); + PyModule_AddIntConstant(m, "CSIDL_PROGRAM_FILES", CSIDL_PROGRAM_FILES); + PyModule_AddIntConstant(m, "CSIDL_PROGRAM_FILES_COMMON", CSIDL_PROGRAM_FILES_COMMON); + PyModule_AddIntConstant(m, "CSIDL_SYSTEM", CSIDL_SYSTEM); + PyModule_AddIntConstant(m, "CSIDL_WINDOWS", CSIDL_WINDOWS); + +} + diff --git a/upload.py b/upload.py index dfec9905c3..4d5dcf5121 100644 --- a/upload.py +++ b/upload.py @@ -29,10 +29,10 @@ BUILD_SCRIPT ='''\ #!/bin/bash cd ~/build && \ rsync -avz --exclude src/calibre/plugins --exclude docs --exclude .bzr --exclude .build --exclude build --exclude dist --exclude "*.pyc" --exclude "*.pyo" rsync://%(host)s/work/%(project)s . && \ -cd %(project)s && \ +cd %(project)s && rm -rf build dist src/calibre/plugins && \ mkdir -p build dist src/calibre/plugins && \ %%s && \ -rm -rf build/* dist/* && \ +rm -rf build/* && \ %%s %%s '''%dict(host=HOST, project=PROJECT) check_call = partial(_check_call, shell=True) @@ -63,6 +63,15 @@ def start_vm(vm, ssh_host, build_script, sleep=75): subprocess.check_call(('scp', t.name, ssh_host+':build-'+PROJECT)) subprocess.check_call('ssh -t %s bash build-%s'%(ssh_host, PROJECT), shell=True) +def run_windows_install_jammer(installer): + ibp = os.path.abspath('installer/windows') + sys.path.insert(0, ibp) + import build_installer + sys.path.remove(ibp) + build_installer.run_install_jammer(installer_name=os.path.basename(installer)) + if not os.path.exists(installer): + raise Exception('Failed to run installjammer') + def build_windows(shutdown=True): installer = installer_name('exe') vm = '/vmware/Windows XP/Windows XP Professional.vmx' @@ -72,20 +81,14 @@ def build_windows(shutdown=True): raise Exception('Failed to run py2exe') if shutdown: subprocess.Popen(('ssh', 'windows', 'shutdown', '-s', '-t', '0')) - ibp = os.path.abspath('installer/windows') - sys.path.insert(0, ibp) - import build_installer - sys.path.remove(ibp) - build_installer.run_install_jammer(installer_name=os.path.basename(installer)) - if not os.path.exists(installer): - raise Exception('Failed to run installjammer') + run_windows_install_jammer(installer) return os.path.basename(installer) def build_osx(shutdown=True): installer = installer_name('dmg') vm = '/vmware/Mac OSX/Mac OSX.vmx' python = '/Library/Frameworks/Python.framework/Versions/Current/bin/python' - start_vm(vm, 'osx', BUILD_SCRIPT%('sudo %s setup.py develop'%python, python, 'osx_installer.py')) + start_vm(vm, 'osx', (BUILD_SCRIPT%('sudo %s setup.py develop'%python, python, 'installer/osx/freeze.py')).replace('rm ', 'sudo rm ')) subprocess.check_call(('scp', 'osx:build/%s/dist/*.dmg'%PROJECT, 'dist')) if not os.path.exists(installer): raise Exception('Failed to build installer '+installer) @@ -97,7 +100,7 @@ def build_osx(shutdown=True): def build_linux(shutdown=True): installer = installer_name('tar.bz2') vm = '/vmware/linux/libprs500-gentoo.vmx' - start_vm(vm, 'linux', BUILD_SCRIPT%('sudo python setup.py develop', 'python','linux_installer.py')) + start_vm(vm, 'linux', (BUILD_SCRIPT%('sudo python setup.py develop', 'python','installer/linux/freeze.py')).replace('rm ', 'sudo rm ')) subprocess.check_call(('scp', 'linux:/tmp/%s'%os.path.basename(installer), 'dist')) if not os.path.exists(installer): raise Exception('Failed to build installer '+installer) From 6b663adcf73b8224a64ac756d10e53a6d74e6e61 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 22 Jul 2008 20:44:27 -0700 Subject: [PATCH 06/34] IGN:... --- .../gui2/pictureflow/PyQt/configure.py | 34 +++++++------------ 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/src/calibre/gui2/pictureflow/PyQt/configure.py b/src/calibre/gui2/pictureflow/PyQt/configure.py index 61115f5fa6..4ab5a28de2 100644 --- a/src/calibre/gui2/pictureflow/PyQt/configure.py +++ b/src/calibre/gui2/pictureflow/PyQt/configure.py @@ -1,4 +1,4 @@ -import os, sys +import os, sys, glob import sipconfig if os.environ.get('PYQT4PATH', None): print os.environ['PYQT4PATH'] @@ -32,32 +32,22 @@ makefile = pyqtconfig.QtGuiModuleMakefile ( qt=1, ) -# Add the library we are wrapping. The name doesn't include any platform -# specific prefixes or extensions (e.g. the "lib" prefix on UNIX, or the -# ".dll" extension on Windows). +# Setup the platform dependent Makefile parameters d = os.path.dirname -makefile.extra_lib_dirs += [os.path.abspath(os.path.join(d(d(d(d(os.getcwd())))), 'plugins')).replace(os.sep, '/')] -makefile.extra_libs += ['pictureflow1' if 'win32' in sys.platform else 'pictureflow'] -makefile.extra_cflags = ['-arch i386', '-arch ppc'] if 'darwin' in sys.platform else [] -makefile.extra_lflags = ['-arch i386', '-arch ppc'] if 'darwin' in sys.platform else [] -makefile.extra_cxxflags = makefile.extra_cflags +if 'darwin' in sys.platform: + makefile.extra_cflags += ['-arch i386', '-arch ppc'] + makefile.extra_lflags += ['-arch i386', '-arch ppc'] +qtdir = os.path.join(d(d(os.getcwd())), '.build') if 'win32' in sys.platform: + qtdir = os.path.join(qtdir, 'release') makefile.extra_lib_dirs += ['C:/Python25/libs'] +# Add the compiled Qt objects +qtobjs = map(lambda x:'"'+x+'"', glob.glob(os.path.join(qtdir, '*.o'))) +makefile.extra_lflags += qtobjs +makefile.extra_cxxflags = makefile.extra_cflags + # Generate the Makefile itself. makefile.generate() -# Now we create the configuration module. This is done by merging a Python -# dictionary (whose values are normally determined dynamically) with a -# (static) template. -content = { - # Publish where the SIP specifications for this module will be - # installed. - "pictureflow_sip_dir": config.default_sip_dir, -} - -# This creates the helloconfig.py module from the helloconfig.py.in -# template and the dictionary. -sipconfig.create_config_module("pictureflowconfig.py", '..'+os.sep+'pictureflowconfig.py.in', content) - From 2a6d01d0a6b41633699162bc25289d337fd96094 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 22 Jul 2008 20:48:37 -0700 Subject: [PATCH 07/34] IGN:... --- setup.py | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/setup.py b/setup.py index 608ffeed26..648872ecc1 100644 --- a/setup.py +++ b/setup.py @@ -72,27 +72,6 @@ if __name__ == '__main__': os.chdir('.build') subprocess.check_call(( (os.path.expanduser('~/qt/bin/qmake') if isosx else 'qmake'), '..'+os.sep+os.path.basename(pro))) subprocess.check_call(['mingw32-make' if iswindows else 'make']) - ext = '.dll' if iswindows else '.dylib' if isosx else '.so' - if iswindows: - pat = re.compile(qtplugin+ver+ext) - elif isosx: - pat = re.compile('lib'+qtplugin+'.'+ver+ext) - else: - pat = re.compile('lib'+qtplugin+ext+'.'+ver+'$') - if iswindows: - os.chdir('release') - qtplugin = None - - for f in glob.glob('*'+ext+'*'): - if pat.match(f): - qtplugin = os.path.realpath(os.path.abspath(f)) - f = os.path.join(cwd, 'src', 'calibre', 'plugins', f) - shutil.copyfile(qtplugin, f) - if islinux: - os.symlink(f, f.rpartition(ext)[0]+ext) - if isosx: - os.symlink(f, f.replace('.'+ver, '')) - break os.chdir(os.path.join('..'+(os.sep+'..' if iswindows else ''), 'PyQt')) if not os.path.exists('.build'): os.mkdir('.build') From cb01eea2f2f54b159bba1b5e8c6fe4814d0966b7 Mon Sep 17 00:00:00 2001 From: "Marshall T. Vandegrift" Date: Wed, 23 Jul 2008 00:20:28 -0400 Subject: [PATCH 08/34] Parse text/x-oeb1-css stylesheets --- src/calibre/ebooks/lrf/html/convert_from.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/calibre/ebooks/lrf/html/convert_from.py b/src/calibre/ebooks/lrf/html/convert_from.py index 6533c6554b..9ffb9e6398 100644 --- a/src/calibre/ebooks/lrf/html/convert_from.py +++ b/src/calibre/ebooks/lrf/html/convert_from.py @@ -1519,7 +1519,8 @@ class HTMLConverter(object, LoggingInterface): css, pcss = self.parse_css(text) ncss.update(css) npcss.update(pcss) - elif tag.has_key('type') and tag['type'] == "text/css" \ + elif tag.has_key('type') \ + and tag['type'] in ("text/css", "text/x-oeb1-css") \ and tag.has_key('href'): path = munge_paths(self.target_prefix, tag['href'])[0] try: From f791a072084ef6e6d9dbbab8b51e1ce5733d3334 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 22 Jul 2008 21:49:23 -0700 Subject: [PATCH 09/34] IGN:... --- .../pictureflow/PyQt/pictureflowconfig.py.in | 22 ------------------- 1 file changed, 22 deletions(-) delete mode 100644 src/calibre/gui2/pictureflow/PyQt/pictureflowconfig.py.in diff --git a/src/calibre/gui2/pictureflow/PyQt/pictureflowconfig.py.in b/src/calibre/gui2/pictureflow/PyQt/pictureflowconfig.py.in deleted file mode 100644 index 40ed93238e..0000000000 --- a/src/calibre/gui2/pictureflow/PyQt/pictureflowconfig.py.in +++ /dev/null @@ -1,22 +0,0 @@ -from PyQt4 import pyqtconfig - -class Configuration(pyqtconfig.Configuration): - - def __init__(self, sub_cfg=None): - """Initialise an instance of the class. - - sub_cfg is the list of sub-class configurations. It should be None - when called normally. - """ - # This is all standard code to be copied verbatim except for the - # name of the module containing the super-class. - if sub_cfg: - cfg = sub_cfg - else: - cfg = [] - - cfg.append(_pkg_config) - - pyqtconfig.Configuration.__init__(self, cfg) - - From 54e5380170af85ea3412cfddb7047087280b8486 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 22 Jul 2008 23:25:22 -0700 Subject: [PATCH 10/34] Fix #904 --- src/calibre/ebooks/lrf/lit/convert_from.py | 9 ++++----- src/calibre/gui2/jobs.py | 2 +- src/calibre/gui2/pictureflow/PyQt/configure.py | 1 - 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/calibre/ebooks/lrf/lit/convert_from.py b/src/calibre/ebooks/lrf/lit/convert_from.py index 66d7b1182e..c9c9c2ee96 100644 --- a/src/calibre/ebooks/lrf/lit/convert_from.py +++ b/src/calibre/ebooks/lrf/lit/convert_from.py @@ -9,7 +9,7 @@ from calibre.ebooks.lit.reader import LitReader from calibre.ebooks import ConversionError from calibre.ebooks.lrf.html.convert_from import process_file as html_process_file from calibre.ebooks.metadata.opf import OPFReader -from calibre import isosx, __appname__, setup_cli_handlers, iswindows, islinux +from calibre import isosx, __appname__, setup_cli_handlers, islinux CLIT = 'clit' if isosx and hasattr(sys, 'frameworks_dir'): @@ -42,10 +42,9 @@ def generate_html(pathtolit, logger): raise ConversionError, 'Cannot read from ' + pathtolit tdir = mkdtemp(prefix=__appname__+'_') os.rmdir(tdir) - sep = r'\\' if iswindows else os.path.sep - cmd = ' '.join([CLIT, '"'+pathtolit+'"', '"%s"'%(tdir+sep,)]) - logger.debug(cmd) - p = Popen(cmd, shell=True, stderr=PIPE, stdout=PIPE) + cmd = [CLIT, pathtolit, '%s'%(tdir+os.sep)] + logger.debug(repr(cmd)) + p = Popen(cmd, stderr=PIPE, stdout=PIPE) stdout = p.stdout.read() err = p.stderr.read() logger.info(p.stdout.read()) diff --git a/src/calibre/gui2/jobs.py b/src/calibre/gui2/jobs.py index 142ab7d920..8e6246d8d9 100644 --- a/src/calibre/gui2/jobs.py +++ b/src/calibre/gui2/jobs.py @@ -126,7 +126,7 @@ class ConversionJob(Job): def formatted_error(self): if self.exception is None: return '' - ans = u'

      %s:'%self.exception + ans = u'

      %s:'%repr(self.exception) ans += '

      Traceback:

      %s
      '%self.last_traceback return ans diff --git a/src/calibre/gui2/pictureflow/PyQt/configure.py b/src/calibre/gui2/pictureflow/PyQt/configure.py index 4ab5a28de2..deb2d51832 100644 --- a/src/calibre/gui2/pictureflow/PyQt/configure.py +++ b/src/calibre/gui2/pictureflow/PyQt/configure.py @@ -1,5 +1,4 @@ import os, sys, glob -import sipconfig if os.environ.get('PYQT4PATH', None): print os.environ['PYQT4PATH'] sys.path.insert(0, os.environ['PYQT4PATH']) From 6cea84a15f0bd708d0cdd6f3bb4e1dbe754344fe Mon Sep 17 00:00:00 2001 From: "Marshall T. Vandegrift" Date: Wed, 23 Jul 2008 10:26:29 -0400 Subject: [PATCH 11/34] Fix NCX playOrder in TOC generated from HTML --- src/calibre/ebooks/metadata/toc.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/calibre/ebooks/metadata/toc.py b/src/calibre/ebooks/metadata/toc.py index 0069505f79..5cecda1c6d 100644 --- a/src/calibre/ebooks/metadata/toc.py +++ b/src/calibre/ebooks/metadata/toc.py @@ -20,7 +20,7 @@ class NCXSoup(BeautifulStoneSoup): class TOC(list): - def __init__(self, href=None, fragment=None, text=None, parent=None, play_order=1, + def __init__(self, href=None, fragment=None, text=None, parent=None, play_order=0, base_path=os.getcwd()): self.href = href self.fragment = fragment @@ -30,7 +30,9 @@ class TOC(list): self.play_order = play_order def add_item(self, href, fragment, text): - self.append(TOC(href=href, fragment=fragment, text=text, parent=self, base_path=self.base_path)) + play_order = (self[-1].play_order if len(self) else self.play_order) + 1 + self.append(TOC(href=href, fragment=fragment, text=text, parent=self, + base_path=self.base_path, play_order=play_order)) return self[-1] def top_level_items(self): @@ -151,4 +153,4 @@ class TOC(list): template = MarkupTemplate(ncx_template) raw = template.generate(uid=uid, toc=self, __appname__=__appname__) raw = raw.render(doctype=doctype) - stream.write(raw) \ No newline at end of file + stream.write(raw) From db9c2096b943c4907895d19517eb604c09baef67 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 23 Jul 2008 08:23:22 -0700 Subject: [PATCH 12/34] IGN:... --- src/calibre/utils/fontconfig.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/calibre/utils/fontconfig.py b/src/calibre/utils/fontconfig.py index e55a4aab53..c061a23b1a 100644 --- a/src/calibre/utils/fontconfig.py +++ b/src/calibre/utils/fontconfig.py @@ -22,7 +22,7 @@ match to a given font specification. The main functions in this module are: .. autofunction:: match ''' -import sys, os, locale, codecs +import sys, os, locale, codecs, platform from ctypes import cdll, c_void_p, Structure, c_int, POINTER, c_ubyte, c_char, util, \ pointer, byref, create_string_buffer, Union, c_char_p, c_double @@ -33,7 +33,8 @@ except: preferred_encoding = 'utf-8' iswindows = 'win32' in sys.platform or 'win64' in sys.platform -isosx = 'darwin' in sys.platform +isosx = 'darwin' in sys.platform +is64bit = '64bit' in platform.architecture()[0] def load_library(): if isosx: From e854a9ffd58b89dc32fdf7589a2fb84e272f89c0 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 24 Jul 2008 20:17:26 -0700 Subject: [PATCH 13/34] Allow syncing of epub books to the 505 --- src/calibre/devices/prs505/books.py | 3 ++- src/calibre/devices/prs505/driver.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/calibre/devices/prs505/books.py b/src/calibre/devices/prs505/books.py index e7e45d78f4..a917aa00ae 100644 --- a/src/calibre/devices/prs505/books.py +++ b/src/calibre/devices/prs505/books.py @@ -20,7 +20,8 @@ MIME_MAP = { 'lrx' : 'application/x-sony-bbeb', "rtf" : "application/rtf", "pdf" : "application/pdf", - "txt" : "text/plain" + "txt" : "text/plain" , + 'epub': 'application/epub+zip', } def uuid(): diff --git a/src/calibre/devices/prs505/driver.py b/src/calibre/devices/prs505/driver.py index bbfbdf037c..4462407e18 100644 --- a/src/calibre/devices/prs505/driver.py +++ b/src/calibre/devices/prs505/driver.py @@ -31,6 +31,7 @@ class PRS505(Device): PRODUCT_ID = 0x031e #: Product Id for the PRS-505 PRODUCT_NAME = 'PRS-505' VENDOR_NAME = 'SONY' + FORMATS = ["lrf", 'epub', "rtf", "pdf", "txt"] MEDIA_XML = 'database/cache/media.xml' CACHE_XML = 'Sony Reader/database/cache.xml' @@ -437,4 +438,4 @@ def main(args=sys.argv): return 0 if __name__ == '__main__': - sys.exit(main()) \ No newline at end of file + sys.exit(main()) From 50add0c72dc80ce77fb6ef12f89d75ca7ca020c0 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 24 Jul 2008 20:26:58 -0700 Subject: [PATCH 14/34] Use a little C code to interface with windows for device detection and unicode command line arguments --- installer/osx/freeze.py | 2 +- setup.py | 17 +- src/calibre/debug.py | 4 + src/calibre/devices/kindle/driver.py | 26 +- src/calibre/devices/scanner.py | 51 +- src/calibre/devices/usbobserver/usbobserver.c | 6 +- src/calibre/manual/faq.rst | 13 +- src/calibre/utils/fontconfig.py | 35 +- src/calibre/utils/windows/Makefile | 18 + src/calibre/utils/windows/winutil.c | 587 ++++++++++++++++++ src/calibre/utils/winutil.c | 99 --- 11 files changed, 682 insertions(+), 176 deletions(-) create mode 100644 src/calibre/utils/windows/Makefile create mode 100644 src/calibre/utils/windows/winutil.c delete mode 100644 src/calibre/utils/winutil.c diff --git a/installer/osx/freeze.py b/installer/osx/freeze.py index ddef24075c..24be7aec0a 100644 --- a/installer/osx/freeze.py +++ b/installer/osx/freeze.py @@ -253,7 +253,7 @@ _check_symlinks_prescript() print 'Adding plugins' module_dir = os.path.join(resource_dir, 'lib', 'python2.5', 'lib-dynload') print 'Adding fontconfig' - for f in glob.glob(os.path.expanduser('~/fontconfig2/*')): + for f in glob.glob(os.path.expanduser('~/fontconfig-bundled/*')): os.link(f, os.path.join(frameworks_dir, os.path.basename(f))) dst = os.path.join(resource_dir, 'fonts') if os.path.exists(dst): diff --git a/setup.py b/setup.py index 648872ecc1..4d2b8247e2 100644 --- a/setup.py +++ b/setup.py @@ -56,10 +56,16 @@ if __name__ == '__main__': include_dirs=['src/calibre/utils/lzx'])] if iswindows: ext_modules.append(Extension('calibre.plugins.winutil', - sources=['src/calibre/utils/winutil.c'], libraries=['shell32']) + sources=['src/calibre/utils/windows/winutil.c'], + libraries=['shell32', 'setupapi'], + include_dirs=['C:/WinDDK/6001.18001/inc/api/']) ) - # Build PyQt extensions - for path in [(os.path.join('src', 'calibre', 'gui2', 'pictureflow'))]: + if isosx: + ext_modules.append(Extension('calibre.plugins.usbobserver', + sources=['src/calibre/driver/usbobserver/usbobserver.c']) + ) + + def build_PyQt_extension(path): pro = glob.glob(os.path.join(path, '*.pro'))[0] raw = open(pro).read() base = qtplugin = re.search(r'TARGET\s*=\s*(.*)', raw).group(1) @@ -72,7 +78,7 @@ if __name__ == '__main__': os.chdir('.build') subprocess.check_call(( (os.path.expanduser('~/qt/bin/qmake') if isosx else 'qmake'), '..'+os.sep+os.path.basename(pro))) subprocess.check_call(['mingw32-make' if iswindows else 'make']) - os.chdir(os.path.join('..'+(os.sep+'..' if iswindows else ''), 'PyQt')) + os.chdir(os.path.join('..', 'PyQt')) if not os.path.exists('.build'): os.mkdir('.build') os.chdir('.build') @@ -142,5 +148,8 @@ if __name__ == '__main__': ] ) + for path in [(os.path.join('src', 'calibre', 'gui2', 'pictureflow'))]: + build_PyQt_extension(path) + if 'develop' in ' '.join(sys.argv) and islinux: subprocess.check_call('calibre_postinstall', shell=True) diff --git a/src/calibre/debug.py b/src/calibre/debug.py index aecff15351..e25fd77c97 100644 --- a/src/calibre/debug.py +++ b/src/calibre/debug.py @@ -23,6 +23,10 @@ Run an embedded python interpreter. return parser def update_zipfile(zipfile, mod, path): + if 'win32' in sys.platform: + print 'WARNING: On Windows Vista you must run this from a console that has been started in Administrator mode.' + print 'Press Enter to continue or Ctrl-C to Cancel' + raw_input() pat = re.compile(mod.replace('.', '/')+r'\.py[co]*') name = mod.replace('.', '/') + os.path.splitext(path)[-1] update(zipfile, [pat], [path], [name]) diff --git a/src/calibre/devices/kindle/driver.py b/src/calibre/devices/kindle/driver.py index 23c5420d4c..93145432db 100755 --- a/src/calibre/devices/kindle/driver.py +++ b/src/calibre/devices/kindle/driver.py @@ -133,31 +133,7 @@ class KINDLE(Device): def open_windows(self): - drives = [] - import wmi - c = wmi.WMI() - for drive in c.Win32_DiskDrive(): - '''print drive.PNPDeviceID''' - if self.__class__.is_device(drive.PNPDeviceID): - if drive.Partitions == 0: - continue - try: - partition = drive.associators("Win32_DiskDriveToDiskPartition")[0] - logical_disk = partition.associators('Win32_LogicalDiskToPartition')[0] - prefix = logical_disk.DeviceID+os.sep - drives.append((drive.Index, prefix)) - except IndexError: - continue - - - if not drives: - print self.__class__.__name__ - raise DeviceError('Unable to find %s. Is it connected?'%(self.__class__.__name__,)) - - drives.sort(cmp=lambda a, b: cmp(a[0], b[0])) - self._main_prefix = drives[0][1] - if len(drives) > 1: - self._card_prefix = drives[1][1] + raise NotImplementedError def open_linux(self): diff --git a/src/calibre/devices/scanner.py b/src/calibre/devices/scanner.py index d0501ab5ff..e896505417 100644 --- a/src/calibre/devices/scanner.py +++ b/src/calibre/devices/scanner.py @@ -7,59 +7,48 @@ manner. import sys -from calibre import iswindows, isosx +from calibre import iswindows, isosx, plugins from calibre.devices import libusb -osx_scanner = None +osx_scanner = win_scanner = linux_scanner = None + try: import usbobserver osx_scanner = usbobserver.get_devices except ImportError: pass -linux_scanner = libusb.get_devices +if iswindows: + try: + win_scanner = plugins['winutil'][0].get_usb_devices + except: + raise RuntimeError('Failed to load the winutil plugin: %s'%plugins['winutil'][1]) +elif isosx: + try: + osx_scanner = plugins['usbobserver'][0].get_usb_devices + except: + raise RuntimeError('Failed to load the usbobserver plugin: %s'%plugins['usbobserver'][1]) +else: + linux_scanner = libusb.get_devices class DeviceScanner(object): - def __init__(self, wmi=None): - self.wmi = wmi - if iswindows and wmi is None: - raise RuntimeError('You must pass a wmi instance to DeviceScanner on windows.') + def __init__(self, *args): if isosx and osx_scanner is None: raise RuntimeError('The Python extension usbobserver must be available on OS X.') if not (isosx or iswindows) and not libusb.has_library(): raise RuntimeError('DeviceScanner requires libusb to work.') - + self.scanner = win_scanner if iswindows else osx_scanner if isosx else linux_scanner self.devices = [] - def get_devices(self): - if iswindows: - devices = [] - for c in self.wmi.USBControllerDevice(): - devices.append(c.Dependent.DeviceID.upper()) - return devices - if isosx: - return osx_scanner() - return linux_scanner() - def scan(self): - try: # Windows WMI occasionally and temporarily barfs - self.devices = self.get_devices() - except Exception, e: - if not iswindows and e: - raise e - + '''Fetch list of connected USB devices from operating system''' + self.devices = self.scanner() def is_device_connected(self, device): if iswindows: for device_id in self.devices: - if 'VEN_'+device.VENDOR_NAME in device_id and \ - 'PROD_'+device.PRODUCT_NAME in device_id: - return True - vid, pid = hex(device.VENDOR_ID)[2:], hex(device.PRODUCT_ID)[2:] - if len(vid) < 4: vid = '0'+vid - if len(pid) < 4: pid = '0'+pid - vid, pid = 'VID_'+vid.upper(), 'PID_'+pid.upper() + vid, pid = 'vid_%4.4x'%device.VENDOR_ID, 'pid_%4.4x'%device.PRODUCT_ID if vid in device_id and pid in device_id: return True return False diff --git a/src/calibre/devices/usbobserver/usbobserver.c b/src/calibre/devices/usbobserver/usbobserver.c index 14dafcad5c..99fe39362d 100644 --- a/src/calibre/devices/usbobserver/usbobserver.c +++ b/src/calibre/devices/usbobserver/usbobserver.c @@ -29,7 +29,7 @@ static PyObject * -usbobserver_get_devices(PyObject *self, PyObject *args) { +usbobserver_get_usb_devices(PyObject *self, PyObject *args) { mach_port_t masterPort; CFMutableDictionaryRef matchingDict; @@ -62,7 +62,7 @@ usbobserver_get_devices(PyObject *self, PyObject *args) { PyObject *devices, *device; devices = PyList_New(0); if (devices == NULL) { - PyErr_SetString(PyExc_RuntimeError, "Out of memory allocating list"); + PyErr_NoMemory(); mach_port_deallocate(mach_task_self(), masterPort); return NULL; } @@ -112,7 +112,7 @@ usbobserver_get_devices(PyObject *self, PyObject *args) { } static PyMethodDef usbobserver_methods[] = { - {"get_devices", usbobserver_get_devices, METH_VARARGS, + {"get_usb_devices", usbobserver_get_usb_devices, METH_VARARGS, "Get list of connected USB devices. Returns a list of tuples. Each tuple is of the form (vendor_id, product_id)." }, {NULL, NULL, 0, NULL} diff --git a/src/calibre/manual/faq.rst b/src/calibre/manual/faq.rst index d130bd9a1b..f2bcbc3022 100644 --- a/src/calibre/manual/faq.rst +++ b/src/calibre/manual/faq.rst @@ -131,13 +131,18 @@ Why does |app| show only some of my fonts on OS X? The graphical user interface of |app| is not starting on Windows? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If you've never used the graphical user interface before, try deleting the file library1.db (it will be somewhere under :file:`C:\\Documents and Settings` on Windows XP and :file:`C:\\Users` on Windows Vista. If that doesn't fix the problem, locate the file calibre.log (in the same places as library1.db) and post its contents in a help message on the `Forums `_. If you can't find either file, try using the windows find feature to search for them. If the files dont exist on your system, try the following: - -Start a command prompt (press the windows key and R and type cmd.exe in the run dialog). At the command prompt type the following command and press Enter:: +There can be several causes for this: + + * **Any windows version**: Search for the files `calibre2.ini` and `calibre.ini` on your computer and delete them. Search for the file `library1.db` and rename it (this file contains all your converted books so deleting it is not a good idea. Now try again. + * **Windows Vista**: If the folder :file:`C:\Users\Your User Name\AppData\Local\VirtualStore\Program Files\calibre` exists, delete it. Uninstall |app|. Reboot. Re-install. + * **Any windows version**: Search your computer for a folder named :file:`_ipython`. Delete it and try again. + +If it still wont launch, start a command prompt (press the windows key and R; then type :command:`cmd.exe` in the Run dialog that appears). At the command prompt type the following command and press Enter:: calibre-debug -c "from calibre.gui2.main import main; main()" -Post any output you see when asking for help. +Post any output you see in a help message on the `Forums Copyright 2008 + +This module contains utility functions to interface with the windows operating +system. It should be compiled with the same version of VisualStudio used to +compile python. It hasn't been tested with MinGW. We try to use unicode +wherever possible in this module. + +.. exception:: winutil.DriveError + Raised when scanning for mounted volumes fails. + +.. function:: is_usb_device_connected(vid : integer, pid : integer) -> bool + Return `True` iff the USB device identified by the VendorID `vid` and + ProductID `pid` is connected to the system. + +.. function:: get_usb_devices() -> list of lowercase strings + Return a list of all USB devices connected to the system. Each + device is represented by a lowercase unicode string whoose format is + the windows *Device Identifier* format. See the MSDN documentation. + +.. function:: get_mounted_volumes_for_usb_device(vid : integer, pid : integer) -> dictionary + Return a dictionary of the form `volume_id`:`drive_letter` for all + volumes mounted from the device specified by `vid` and `pid`. + + :raises: :exception:`winutil.DriveError` if scanning fails. + +.. function:: special_folder_path(csidl_id) -> path + Get paths to common system folders. + See windows documentation of SHGetFolderPath. + The paths are returned as unicode objects. `csidl_id` should be one + of the symbolic constants defined in this module. You can also `OR` + a symbolic constant with :data:`CSIDL_FLAG_CREATE` to force the operating + system to create a folder if it does not exist. For example:: + + >>> from winutil import * + >>> special_folder_path(CSIDL_APPDATA) + u'C:\\Documents and Settings\\Kovid Goyal\\Application Data' + >>> special_folder_path(CSIDL_PERSONAL) + u'C:\\Documents and Settings\\Kovid Goyal\\My Documents' + +.. function:: argv() -> list of unicode command line arguments + Get command line arguments as unicode objects. Note that the + first argument will be the path to the interpreter, *not* the + script being run. So to replace sys.argv, you should use + sys.argv[1:] = winutil.argv()[1:]. + +*/ + + +#define UNICODE +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUFSIZE 512 +#define MAX_DRIVES 26 +static PyObject *DriveError; +static BOOL DEBUG = FALSE; + +//#define debug(fmt, ...) if DEBUG printf(x, __VA_ARGS__); +void +debug(const char *fmt, ...) { + va_list argList; + va_start(argList, fmt); + if (DEBUG) vprintf(fmt, argList); + va_end(argList); +} + +struct tagDrives +{ + WCHAR letter; + WCHAR volume[BUFSIZE]; +}; + +static PyObject * +winutil_folder_path(PyObject *self, PyObject *args) { + int res; DWORD dwFlags; + PyObject *ans = NULL; + TCHAR wbuf[MAX_PATH]; CHAR buf[4*MAX_PATH]; + memset(wbuf, 0, sizeof(TCHAR)*MAX_PATH); memset(buf, 0, sizeof(CHAR)*MAX_PATH); + + if (!PyArg_ParseTuple(args, "l", &dwFlags)) return NULL; + + res = SHGetFolderPath(NULL, dwFlags, NULL, 0, wbuf); + if (res != S_OK) { + if (res == E_FAIL) PyErr_SetString(PyExc_ValueError, "Folder does not exist."); + PyErr_SetString(PyExc_ValueError, "Folder not valid"); + return NULL; + } + res = WideCharToMultiByte(CP_UTF8, 0, wbuf, -1, buf, 4*MAX_PATH, NULL, NULL); + ans = PyUnicode_DecodeUTF8(buf, res-1, "strict"); + return ans; +} + +static PyObject * +winutil_argv(PyObject *self, PyObject *args) { + PyObject *argv, *v; + LPWSTR *_argv; + LPSTR buf; + int argc, i, bytes; + if (!PyArg_ParseTuple(args, "")) return NULL; + _argv = CommandLineToArgvW(GetCommandLine(), &argc); + if (_argv == NULL) { PyErr_NoMemory(); return NULL; } + argv = PyList_New(argc); + if (argv != NULL) { + for (i = 0; i < argc; i++) { + bytes = WideCharToMultiByte(CP_UTF8, 0, _argv[i], -1, NULL, 0, NULL, NULL); + buf = (LPSTR)PyMem_Malloc(sizeof(CHAR)*bytes); + if (buf == NULL) { Py_DECREF(argv); argv = NULL; break; } + WideCharToMultiByte(CP_UTF8, 0, _argv[i], -1, buf, bytes, NULL, NULL); + v = PyUnicode_DecodeUTF8(buf, bytes-1, "strict"); + PyMem_Free(buf); + if (v == NULL) { Py_DECREF(argv); argv = NULL; break; } + PyList_SetItem(argv, i, v); + } + } + LocalFree(_argv); + return argv; +} + +static LPVOID +format_last_error() { + /* Format the last error as a string. The returned pointer should + be freed with :cfunction:`LocalFree(lpMsgBuf)`. It can be printed with + :cfunction:`printf("\n%ws\n", (LPCTSTR)lpMsgBuf)`. + */ + + LPVOID lpMsgBuf; + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + 0, // Default language + (LPTSTR) &lpMsgBuf, + 0, + NULL + ); + return lpMsgBuf; +} + +static PyObject * +winutil_set_debug(PyObject *self, PyObject *args) { + PyObject *yes; + if (!PyArg_ParseTuple(args, "O", &yes)) return NULL; + DEBUG = (BOOL)PyObject_IsTrue(yes); + return Py_None; +} + +static LPTSTR +get_registry_property(HDEVINFO hDevInfo, DWORD index, DWORD property, BOOL *iterate) { + /* Get a the property specified by `property` from the registry for the + * device enumerated by `index` in the collection `hDevInfo`. `iterate` + * will be set to `FALSE` if `index` points outside `hDevInfo`. + * :return: A string allocated on the heap containing the property or + * `NULL` if an error occurred. + */ + SP_DEVINFO_DATA DeviceInfoData; + DWORD DataT; + LPTSTR buffer = NULL; + DWORD buffersize = 0; + DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); + + if (!SetupDiEnumDeviceInfo(hDevInfo, index, &DeviceInfoData)) { + *iterate = FALSE; + return NULL; + } + + while(!SetupDiGetDeviceRegistryProperty( + hDevInfo, + &DeviceInfoData, + property, + &DataT, + (PBYTE)buffer, + buffersize, + &buffersize)) { + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + buffer = (LPTSTR)PyMem_Malloc(2*buffersize); // Twice for bug in Win2k + } else { + PyMem_Free(buffer); + PyErr_SetFromWindowsErr(0); + buffer = NULL; + break; + } + } //while + + return buffer; +} + +static BOOL +check_device_id(LPTSTR buffer, unsigned int vid, unsigned int pid) { + WCHAR xVid[9], dVid[9], xPid[9], dPid[9]; + unsigned int j; + swprintf(xVid, L"vid_%4.4x", vid); + swprintf(dVid, L"vid_%4.4d", vid); + swprintf(xPid, L"pid_%4.4x", pid); + swprintf(dPid, L"pid_%4.4d", pid); + + for (j = 0; j < wcslen(buffer); j++) buffer[j] = tolower(buffer[j]); + + return ( (wcsstr(buffer, xVid) != NULL || wcsstr(buffer, dVid) != NULL ) && + (wcsstr(buffer, xPid) != NULL || wcsstr(buffer, dPid) != NULL ) + ); +} + + +static HDEVINFO +create_device_info_set(LPGUID guid, PCTSTR enumerator, HWND parent, DWORD flags) { + HDEVINFO hDevInfo; + hDevInfo = SetupDiGetClassDevs( + guid, + enumerator, + parent, + flags + ); + if (hDevInfo == INVALID_HANDLE_VALUE) { + PyErr_SetFromWindowsErr(0); + } + return hDevInfo; +} + +int n; + +BOOL +get_all_removable_disks(struct tagDrives *g_drives) +{ + WCHAR caDrive[4]; + WCHAR volume[BUFSIZE]; + int nLoopIndex; + DWORD dwDriveMask; + unsigned int g_count=0; + + + caDrive[0] = 'A'; + caDrive[1] = ':'; + caDrive[2] = '\\'; + caDrive[3] = 0; + + + + + + // Get all drives in the system. + dwDriveMask = GetLogicalDrives(); + + + if(dwDriveMask == 0) + { + PyErr_SetString(DriveError, "GetLogicalDrives failed"); + return FALSE; + } + + + // Loop for all drives (MAX_DRIVES = 26) + + + for(nLoopIndex = 0; nLoopIndex< MAX_DRIVES; nLoopIndex++) + { + // if a drive is present, + if(dwDriveMask & 1) + { + caDrive[0] = 'A' + nLoopIndex; + + + // If a drive is removable + if(GetDriveType(caDrive) == DRIVE_REMOVABLE) + { + //Get its volume info and store it in the global variable. + if(GetVolumeNameForVolumeMountPoint(caDrive, volume, BUFSIZE)) + { + g_drives[g_count].letter = caDrive[0]; + wcscpy(g_drives[g_count].volume, volume); + g_count ++; + } + + } + } + dwDriveMask >>= 1; + } + + + // success if atleast one removable drive is found. + if(g_count == 0) + { + PyErr_SetString(DriveError, "No removable drives found"); + return FALSE; + } + return TRUE; + +} + +PSP_DEVICE_INTERFACE_DETAIL_DATA +get_device_grandparent(HDEVINFO hDevInfo, DWORD index, PWSTR buf, PWSTR volume_id, + BOOL *iterate) { + SP_DEVICE_INTERFACE_DATA interfaceData; + SP_DEVINFO_DATA devInfoData; + BOOL status; + PSP_DEVICE_INTERFACE_DETAIL_DATA interfaceDetailData; + DWORD interfaceDetailDataSize, + reqSize; + DEVINST parent; + + interfaceData.cbSize = sizeof (SP_INTERFACE_DEVICE_DATA); + devInfoData.cbSize = sizeof (SP_DEVINFO_DATA); + + status = SetupDiEnumDeviceInterfaces ( + hDevInfo, // Interface Device Info handle + NULL, // Device Info data + (LPGUID)&GUID_DEVINTERFACE_VOLUME, // Interface registered by driver + index, // Member + &interfaceData // Device Interface Data + ); + if ( status == FALSE ) { + *iterate = FALSE; + return NULL; + } + SetupDiGetDeviceInterfaceDetail ( + hDevInfo, // Interface Device info handle + &interfaceData, // Interface data for the event class + NULL, // Checking for buffer size + 0, // Checking for buffer size + &reqSize, // Buffer size required to get the detail data + NULL // Checking for buffer size + ); + + interfaceDetailDataSize = reqSize; + interfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)PyMem_Malloc(interfaceDetailDataSize+10); + if ( interfaceDetailData == NULL ) { + PyErr_NoMemory(); + return NULL; + } + interfaceDetailData->cbSize = sizeof (SP_INTERFACE_DEVICE_DETAIL_DATA); + + status = SetupDiGetDeviceInterfaceDetail ( + hDevInfo, // Interface Device info handle + &interfaceData, // Interface data for the event class + interfaceDetailData, // Interface detail data + interfaceDetailDataSize, // Interface detail data size + &reqSize, // Buffer size required to get the detail data + &devInfoData); // Interface device info + + if ( status == FALSE ) {PyErr_SetFromWindowsErr(0); PyMem_Free(interfaceDetailData); return NULL;} + + // Get the device instance of parent. This points to USBSTOR. + CM_Get_Parent(&parent, devInfoData.DevInst, 0); + // Get the device ID of the USBSTORAGE volume + CM_Get_Device_ID(parent, volume_id, BUFSIZE, 0); + // Get the device instance of grand parent. This points to USB root. + CM_Get_Parent(&parent, parent, 0); + // Get the device ID of the USB root. + CM_Get_Device_ID(parent, buf, BUFSIZE, 0); + + return interfaceDetailData; +} + +static PyObject * +winutil_get_mounted_volumes_for_usb_device(PyObject *self, PyObject *args) { + unsigned int vid, pid, length, j; + HDEVINFO hDevInfo; + BOOL iterate = TRUE; + PSP_DEVICE_INTERFACE_DETAIL_DATA interfaceDetailData; + DWORD i; + WCHAR buf[BUFSIZE], volume[BUFSIZE], volume_id[BUFSIZE]; + struct tagDrives g_drives[MAX_DRIVES]; + PyObject *volumes, *key, *val; + + if (!PyArg_ParseTuple(args, "ii", &vid, &pid)) { + return NULL; + } + + volumes = PyDict_New(); + if (volumes == NULL) return NULL; + + for (j = 0; j < MAX_DRIVES; j++) g_drives[j].letter = 0; + + // Find all removable drives + if (!get_all_removable_disks(g_drives)) { + return NULL; + } + + hDevInfo = create_device_info_set((LPGUID)&GUID_DEVINTERFACE_VOLUME, + NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); + if (hDevInfo == INVALID_HANDLE_VALUE) return NULL; + + // Enumerate through the set + for (i=0; iterate; i++) { + interfaceDetailData = get_device_grandparent(hDevInfo, i, buf, volume_id, &iterate); + if (interfaceDetailData == NULL) { + PyErr_Print(); continue; + } + debug("Device num: %d Device Id: %ws\n\n", i, buf); + if (check_device_id(buf, vid, pid)) { + debug("Device matches\n\n"); + length = wcslen(interfaceDetailData->DevicePath); + interfaceDetailData->DevicePath[length] = '\\'; + interfaceDetailData->DevicePath[length+1] = 0; + if(GetVolumeNameForVolumeMountPoint(interfaceDetailData->DevicePath, volume, BUFSIZE)) { + + for(j = 0; j < MAX_DRIVES; j++) { + // Compare volume mount point with the one stored earlier. + // If both match, return the corresponding drive letter. + if(g_drives[j].letter != 0 && wcscmp(g_drives[j].volume, volume)==0) + { + key = PyUnicode_FromWideChar(volume_id, wcslen(volume_id)); + val = PyString_FromFormat("%c", (char)g_drives[j].letter); + if (key == NULL || val == NULL) { + PyErr_NoMemory(); + PyMem_Free(interfaceDetailData); + return NULL; + } + PyDict_SetItem(volumes, key, val); + } + } + + } else { + debug("Failed to get volume name for volume mount point:\n"); + if (DEBUG) debug("%ws\n\n", format_last_error()); + } + + PyMem_Free(interfaceDetailData); + } + + } //for + + SetupDiDestroyDeviceInfoList(hDevInfo); + return volumes; + +} + +static PyObject * +winutil_get_usb_devices(PyObject *self, PyObject *args) { + unsigned int j, buffersize; + HDEVINFO hDevInfo; + DWORD i; BOOL iterate = TRUE; + PyObject *devices, *temp = (PyObject *)1; + LPTSTR buffer; + + if (!PyArg_ParseTuple(args, "")) return NULL; + + devices = PyList_New(0); + if (devices == NULL) {PyErr_NoMemory(); return NULL;} + + // Create a Device information set with all USB devices + hDevInfo = create_device_info_set(NULL, L"USB", 0, + DIGCF_PRESENT | DIGCF_ALLCLASSES); + if (hDevInfo == INVALID_HANDLE_VALUE) + return NULL; + // Enumerate through the set + for (i=0; iterate; i++) { + buffer = get_registry_property(hDevInfo, i, SPDRP_HARDWAREID, &iterate); + if (buffer == NULL) { + PyErr_Print(); continue; + } + buffersize = wcslen(buffer); + for (j = 0; j < buffersize; j++) buffer[j] = tolower(buffer[j]); + temp = PyUnicode_FromWideChar(buffer, buffersize); + PyMem_Free(buffer); + if (temp == NULL) { + PyErr_NoMemory(); + break; + } + PyList_Append(devices, temp); + } //for + if (temp == NULL) { Py_DECREF(devices); devices = NULL; } + SetupDiDestroyDeviceInfoList(hDevInfo); + return devices; +} + + +static PyObject * +winutil_is_usb_device_connected(PyObject *self, PyObject *args) { + unsigned int vid, pid; + HDEVINFO hDevInfo; + DWORD i; BOOL iterate = TRUE; + LPTSTR buffer; + int found = FALSE; + PyObject *ans; + + if (!PyArg_ParseTuple(args, "ii", &vid, &pid)) { + return NULL; + } + + // Create a Device information set with all USB devices + hDevInfo = create_device_info_set(NULL, L"USB", 0, + DIGCF_PRESENT | DIGCF_ALLCLASSES); + if (hDevInfo == INVALID_HANDLE_VALUE) + return NULL; + + // Enumerate through the set + for (i=0; iterate && !found; i++) { + buffer = get_registry_property(hDevInfo, i, SPDRP_HARDWAREID, &iterate); + if (buffer == NULL) { + PyErr_Print(); continue; + } + found = check_device_id(buffer, vid, pid); + PyMem_Free(buffer); + } // for + + SetupDiDestroyDeviceInfoList(hDevInfo); + ans = (found) ? Py_True : Py_False; + Py_INCREF(ans); + return ans; +} + + +static PyMethodDef WinutilMethods[] = { + {"special_folder_path", winutil_folder_path, METH_VARARGS, + "special_folder_path(csidl_id) -> path\n\n" + "Get paths to common system folders. " + "See windows documentation of SHGetFolderPath. " + "The paths are returned as unicode objects. csidl_id should be one " + "of the symbolic constants defined in this module. You can also OR " + "a symbolic constant with CSIDL_FLAG_CREATE to force the operating " + "system to create a folder if it does not exist."}, + + {"argv", winutil_argv, METH_VARARGS, + "argv() -> list of command line arguments\n\n" + "Get command line arguments as unicode objects. Note that the " + "first argument will be the path to the interpreter, *not* the " + "script being run. So to replace sys.argv, you should use " + "sys.argv[1:] = argv()[1:]."}, + + {"is_usb_device_connected", winutil_is_usb_device_connected, METH_VARARGS, + "is_usb_device_connected(vid, pid) -> bool\n\n" + "Check if the USB device identified by VendorID: vid (integer) and" + " ProductID: pid (integer) is currently connected."}, + + {"get_usb_devices", winutil_get_usb_devices, METH_VARARGS, + "get_usb_devices() -> list of strings\n\n" + "Return a list of the hardware IDs of all USB devices " + "connected to the system."}, + + {"get_mounted_volumes_for_usb_device", winutil_get_mounted_volumes_for_usb_device, METH_VARARGS, + "get_mounted_volumes_for_usb_device(vid, pid) -> dict\n\n" + "Return a dictionary of volume_id:drive_letter for all" + "volumes mounted on the system that belong to the" + "usb device specified by vid (integer) and pid (integer)."}, + + {"set_debug", winutil_set_debug, METH_VARARGS, + "set_debug(bool)\n\nSet debugging mode." + }, + + {NULL, NULL, 0, NULL} +}; + +PyMODINIT_FUNC +initwinutil(void) { + PyObject *m; + m = Py_InitModule3("winutil", WinutilMethods, + "Defines utility methods to interface with windows." + ); + if (m == NULL) return; + DriveError = PyErr_NewException("winutil.DriveError", NULL, NULL); + + PyModule_AddIntConstant(m, "CSIDL_ADMINTOOLS", CSIDL_ADMINTOOLS); + PyModule_AddIntConstant(m, "CSIDL_APPDATA", CSIDL_APPDATA); + PyModule_AddIntConstant(m, "CSIDL_COMMON_ADMINTOOLS", CSIDL_COMMON_ADMINTOOLS); + PyModule_AddIntConstant(m, "CSIDL_COMMON_APPDATA", CSIDL_COMMON_APPDATA); + PyModule_AddIntConstant(m, "CSIDL_COMMON_DOCUMENTS", CSIDL_COMMON_DOCUMENTS); + PyModule_AddIntConstant(m, "CSIDL_COOKIES", CSIDL_COOKIES); + PyModule_AddIntConstant(m, "CSIDL_FLAG_CREATE", CSIDL_FLAG_CREATE); + PyModule_AddIntConstant(m, "CSIDL_FLAG_DONT_VERIFY", CSIDL_FLAG_DONT_VERIFY); + PyModule_AddIntConstant(m, "CSIDL_HISTORY", CSIDL_HISTORY); + PyModule_AddIntConstant(m, "CSIDL_INTERNET_CACHE", CSIDL_INTERNET_CACHE); + PyModule_AddIntConstant(m, "CSIDL_LOCAL_APPDATA", CSIDL_LOCAL_APPDATA); + PyModule_AddIntConstant(m, "CSIDL_MYPICTURES", CSIDL_MYPICTURES); + PyModule_AddIntConstant(m, "CSIDL_PERSONAL", CSIDL_PERSONAL); + PyModule_AddIntConstant(m, "CSIDL_PROGRAM_FILES", CSIDL_PROGRAM_FILES); + PyModule_AddIntConstant(m, "CSIDL_PROGRAM_FILES_COMMON", CSIDL_PROGRAM_FILES_COMMON); + PyModule_AddIntConstant(m, "CSIDL_SYSTEM", CSIDL_SYSTEM); + PyModule_AddIntConstant(m, "CSIDL_WINDOWS", CSIDL_WINDOWS); + +} + diff --git a/src/calibre/utils/winutil.c b/src/calibre/utils/winutil.c deleted file mode 100644 index 04a4c3a49b..0000000000 --- a/src/calibre/utils/winutil.c +++ /dev/null @@ -1,99 +0,0 @@ -#define UNICODE -#include -#include -#include -#include - - -static PyObject * -winutil_folder_path(PyObject *self, PyObject *args) { - int res; DWORD dwFlags; - PyObject *ans = NULL; - TCHAR wbuf[MAX_PATH]; CHAR buf[4*MAX_PATH]; - memset(wbuf, 0, sizeof(TCHAR)*MAX_PATH); memset(buf, 0, sizeof(CHAR)*MAX_PATH); - - if (!PyArg_ParseTuple(args, "l", &dwFlags)) return NULL; - - res = SHGetFolderPath(NULL, dwFlags, NULL, 0, wbuf); - if (res != S_OK) { - if (res == E_FAIL) PyErr_SetString(PyExc_ValueError, "Folder does not exist."); - PyErr_SetString(PyExc_ValueError, "Folder not valid"); - return NULL; - } - res = WideCharToMultiByte(CP_UTF8, 0, wbuf, -1, buf, 4*MAX_PATH, NULL, NULL); - ans = PyUnicode_DecodeUTF8(buf, res-1, "strict"); - return ans; -} - -static PyObject * -winutil_argv(PyObject *self, PyObject *args) { - PyObject *argv, *v; - LPWSTR *_argv; - LPSTR buf; - int argc, i, bytes; - if (!PyArg_ParseTuple(args, "")) return NULL; - _argv = CommandLineToArgvW(GetCommandLine(), &argc); - if (_argv == NULL) { PyErr_SetString(PyExc_RuntimeError, "Out of memory."); return NULL; } - argv = PyList_New(argc); - if (argv != NULL) { - for (i = 0; i < argc; i++) { - bytes = WideCharToMultiByte(CP_UTF8, 0, _argv[i], -1, NULL, 0, NULL, NULL); - buf = (LPSTR)PyMem_Malloc(sizeof(CHAR)*bytes); - if (buf == NULL) { Py_DECREF(argv); argv = NULL; break; } - WideCharToMultiByte(CP_UTF8, 0, _argv[i], -1, buf, bytes, NULL, NULL); - v = PyUnicode_DecodeUTF8(buf, bytes-1, "strict"); - PyMem_Free(buf); - if (v == NULL) { Py_DECREF(argv); argv = NULL; break; } - PyList_SetItem(argv, i, v); - } - } - LocalFree(_argv); - return argv; -} - -static PyMethodDef WinutilMethods[] = { - {"folder_path", winutil_folder_path, METH_VARARGS, - "folder_path(csidl_id) -> path\n\n" - "Get paths to common system folders. " - "See windows documentation of SHGetFolderPath. " - "The paths are returned as unicode objects. csidl_id should be one " - "of the symbolic constants defined in this module. You can also OR " - "a symbolic constant with CSIDL_FLAG_CREATE to force the operating " - "system to create a folder if it does not exist."}, - {"argv", winutil_argv, METH_VARARGS, - "argv() -> list of command line arguments\n\n" - "Get command line arguments as unicode objects. Note that the " - "first argument will be the path to the interpreter, *not* the " - "script being run. So to replace sys.argv, you should use " - "sys.argv[1:] = argv()[1:]."}, - - {NULL, NULL, 0, NULL} -}; - -PyMODINIT_FUNC -initwinutil(void) { - PyObject *m; - m = Py_InitModule3("winutil", WinutilMethods, - "Defines utility methods to interface with windows." - ); - if (m == NULL) return; - PyModule_AddIntConstant(m, "CSIDL_ADMINTOOLS", CSIDL_ADMINTOOLS); - PyModule_AddIntConstant(m, "CSIDL_APPDATA", CSIDL_APPDATA); - PyModule_AddIntConstant(m, "CSIDL_COMMON_ADMINTOOLS", CSIDL_COMMON_ADMINTOOLS); - PyModule_AddIntConstant(m, "CSIDL_COMMON_APPDATA", CSIDL_COMMON_APPDATA); - PyModule_AddIntConstant(m, "CSIDL_COMMON_DOCUMENTS", CSIDL_COMMON_DOCUMENTS); - PyModule_AddIntConstant(m, "CSIDL_COOKIES", CSIDL_COOKIES); - PyModule_AddIntConstant(m, "CSIDL_FLAG_CREATE", CSIDL_FLAG_CREATE); - PyModule_AddIntConstant(m, "CSIDL_FLAG_DONT_VERIFY", CSIDL_FLAG_DONT_VERIFY); - PyModule_AddIntConstant(m, "CSIDL_HISTORY", CSIDL_HISTORY); - PyModule_AddIntConstant(m, "CSIDL_INTERNET_CACHE", CSIDL_INTERNET_CACHE); - PyModule_AddIntConstant(m, "CSIDL_LOCAL_APPDATA", CSIDL_LOCAL_APPDATA); - PyModule_AddIntConstant(m, "CSIDL_MYPICTURES", CSIDL_MYPICTURES); - PyModule_AddIntConstant(m, "CSIDL_PERSONAL", CSIDL_PERSONAL); - PyModule_AddIntConstant(m, "CSIDL_PROGRAM_FILES", CSIDL_PROGRAM_FILES); - PyModule_AddIntConstant(m, "CSIDL_PROGRAM_FILES_COMMON", CSIDL_PROGRAM_FILES_COMMON); - PyModule_AddIntConstant(m, "CSIDL_SYSTEM", CSIDL_SYSTEM); - PyModule_AddIntConstant(m, "CSIDL_WINDOWS", CSIDL_WINDOWS); - -} - From 49f75513cfc968820ae51b96d911ec966b77725b Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 25 Jul 2008 00:01:31 -0700 Subject: [PATCH 15/34] version 0.4.80 --- setup.py | 2 +- src/calibre/__init__.py | 6 ++++-- src/calibre/devices/scanner.py | 16 +++++----------- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/setup.py b/setup.py index 4d2b8247e2..fdb0afad90 100644 --- a/setup.py +++ b/setup.py @@ -62,7 +62,7 @@ if __name__ == '__main__': ) if isosx: ext_modules.append(Extension('calibre.plugins.usbobserver', - sources=['src/calibre/driver/usbobserver/usbobserver.c']) + sources=['src/calibre/devices/usbobserver/usbobserver.c']) ) def build_PyQt_extension(path): diff --git a/src/calibre/__init__.py b/src/calibre/__init__.py index 1568dc8710..65f1151e46 100644 --- a/src/calibre/__init__.py +++ b/src/calibre/__init__.py @@ -1,7 +1,7 @@ ''' E-book management software''' __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' -__version__ = '0.4.79' +__version__ = '0.4.80' __docformat__ = "epytext" __author__ = "Kovid Goyal " __appname__ = 'calibre' @@ -61,7 +61,9 @@ if iswindows and getattr(sys, 'frozen', False): plugins = {} -for plugin in ['pictureflow', 'lzx'] + (['winutil'] if iswindows else []): +for plugin in ['pictureflow', 'lzx'] + \ + (['winutil'] if iswindows else []) + \ + (['usbobserver'] if isosx else []): try: p, err = __import__(plugin), '' except Exception, err: diff --git a/src/calibre/devices/scanner.py b/src/calibre/devices/scanner.py index e896505417..ae14f06692 100644 --- a/src/calibre/devices/scanner.py +++ b/src/calibre/devices/scanner.py @@ -12,12 +12,6 @@ from calibre.devices import libusb osx_scanner = win_scanner = linux_scanner = None -try: - import usbobserver - osx_scanner = usbobserver.get_devices -except ImportError: - pass - if iswindows: try: win_scanner = plugins['winutil'][0].get_usb_devices @@ -28,11 +22,11 @@ elif isosx: osx_scanner = plugins['usbobserver'][0].get_usb_devices except: raise RuntimeError('Failed to load the usbobserver plugin: %s'%plugins['usbobserver'][1]) -else: +else: linux_scanner = libusb.get_devices class DeviceScanner(object): - + def __init__(self, *args): if isosx and osx_scanner is None: raise RuntimeError('The Python extension usbobserver must be available on OS X.') @@ -40,11 +34,11 @@ class DeviceScanner(object): raise RuntimeError('DeviceScanner requires libusb to work.') self.scanner = win_scanner if iswindows else osx_scanner if isosx else linux_scanner self.devices = [] - + def scan(self): '''Fetch list of connected USB devices from operating system''' self.devices = self.scanner() - + def is_device_connected(self, device): if iswindows: for device_id in self.devices: @@ -63,4 +57,4 @@ def main(args=sys.argv): return 0 if __name__ == '__main__': - sys.exit(main()) \ No newline at end of file + sys.exit(main()) From 74196b30b2dd6640237b98951fead3b55e1d70d6 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 25 Jul 2008 00:04:41 -0700 Subject: [PATCH 16/34] IGN:Tag release From 9a400ae39ae59da17ceca109c0ed966a22ca8b49 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 25 Jul 2008 08:02:02 -0700 Subject: [PATCH 17/34] IGN:... --- installer/windows/calibre/calibre.mpi | 1 - setup.py | 80 +++++++++---------- .../trac/plugins/templates/distro.html | 3 +- .../trac/plugins/templates/pyinstaller.html | 2 +- upload.py | 6 +- 5 files changed, 46 insertions(+), 46 deletions(-) diff --git a/installer/windows/calibre/calibre.mpi b/installer/windows/calibre/calibre.mpi index 63d812f041..3dc587e603 100644 --- a/installer/windows/calibre/calibre.mpi +++ b/installer/windows/calibre/calibre.mpi @@ -353,7 +353,6 @@ File ::36E8EEAC-F54D-5DE9-02D8-ECDFEBB4B5E2 -type dir -name plugins -parent 6CCF File ::71930E14-A27B-C23C-8D94-C7E97ADB8723 -name pictureflow.pyd -parent 36E8EEAC-F54D-5DE9-02D8-ECDFEBB4B5E2 File ::293E6ABE-17C9-5E53-1B44-C27029C8C061 -name winutil.pyd -parent 36E8EEAC-F54D-5DE9-02D8-ECDFEBB4B5E2 File ::A5737158-18DF-7F20-2BDF-2DF615663891 -name lzx.pyd -parent 36E8EEAC-F54D-5DE9-02D8-ECDFEBB4B5E2 -File ::87085EC3-26D5-975D-A820-0691F193733D -name pictureflow1.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 File ::CA9E098C-2931-9781-1303-213C242F9A5E -name lit2oeb.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 File ::16B5A447-066C-C93E-F63D-8BC0D57CA544 -name lit2oeb.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 Component ::F6829AB7-9F66-4CEE-CA0E-21F54C6D3609 -setup Install -active Yes -platforms {AIX-ppc FreeBSD-4-x86 FreeBSD-x86 HPUX-hppa Linux-x86 Solaris-sparc Windows} -name Main -parent Components diff --git a/setup.py b/setup.py index fdb0afad90..03cd53efe5 100644 --- a/setup.py +++ b/setup.py @@ -48,15 +48,15 @@ main_functions = { if __name__ == '__main__': from setuptools import setup, find_packages, Extension import subprocess, glob - + entry_points['console_scripts'].append('calibre_postinstall = calibre.linux:post_install') ext_modules = [Extension('calibre.plugins.lzx', - sources=['src/calibre/utils/lzx/lzxmodule.c', + sources=['src/calibre/utils/lzx/lzxmodule.c', 'src/calibre/utils/lzx/lzxd.c'], include_dirs=['src/calibre/utils/lzx'])] if iswindows: ext_modules.append(Extension('calibre.plugins.winutil', - sources=['src/calibre/utils/windows/winutil.c'], + sources=['src/calibre/utils/windows/winutil.c'], libraries=['shell32', 'setupapi'], include_dirs=['C:/WinDDK/6001.18001/inc/api/']) ) @@ -64,7 +64,7 @@ if __name__ == '__main__': ext_modules.append(Extension('calibre.plugins.usbobserver', sources=['src/calibre/devices/usbobserver/usbobserver.c']) ) - + def build_PyQt_extension(path): pro = glob.glob(os.path.join(path, '*.pro'))[0] raw = open(pro).read() @@ -97,59 +97,59 @@ if __name__ == '__main__': os.unlink(f) except: continue - + + for path in [(os.path.join('src', 'calibre', 'gui2', 'pictureflow'))]: + build_PyQt_extension(path) + setup( - name=APPNAME, - packages = find_packages('src'), - package_dir = { '' : 'src' }, - version=VERSION, - author='Kovid Goyal', - author_email='kovid@kovidgoyal.net', - url = 'http://%s.kovidgoyal.net'%APPNAME, + name=APPNAME, + packages = find_packages('src'), + package_dir = { '' : 'src' }, + version=VERSION, + author='Kovid Goyal', + author_email='kovid@kovidgoyal.net', + url = 'http://%s.kovidgoyal.net'%APPNAME, package_data = {'calibre':['plugins/*']}, include_package_data=True, - entry_points = entry_points, + entry_points = entry_points, zip_safe = False, options = { 'bdist_egg' : {'exclude_source_files': True,}, }, ext_modules=ext_modules, - description = + description = ''' E-book management application. - ''', - long_description = + ''', + long_description = ''' %s is an e-book library manager. It can view, convert and catalog e-books in most of the major e-book formats. It can also talk to a few e-book reader devices. It can go out to the internet and fetch metadata for your books. It can download newspapers and convert them into e-books for convenient reading. It is cross platform, running on Linux, Windows and OS X. - + For screenshots: https://%s.kovidgoyal.net/wiki/Screenshots - - For installation/usage instructions please see + + For installation/usage instructions please see http://%s.kovidgoyal.net - - For source code access: - bzr branch http://bzr.kovidgoyal.net/code/%s/trunk %s - - To update your copy of the source code: + + For source code access: + bzr branch http://bzr.kovidgoyal.net/code/%s/trunk %s + + To update your copy of the source code: bzr merge - + '''%(APPNAME, APPNAME, APPNAME, APPNAME, APPNAME), - license = 'GPL', + license = 'GPL', classifiers = [ - 'Development Status :: 4 - Beta', - 'Environment :: Console', - 'Environment :: X11 Applications :: Qt', - 'Intended Audience :: Developers', - 'Intended Audience :: End Users/Desktop', - 'License :: OSI Approved :: GNU General Public License (GPL)', - 'Natural Language :: English', - 'Operating System :: POSIX :: Linux', - 'Programming Language :: Python', - 'Topic :: Software Development :: Libraries :: Python Modules', + 'Development Status :: 4 - Beta', + 'Environment :: Console', + 'Environment :: X11 Applications :: Qt', + 'Intended Audience :: Developers', + 'Intended Audience :: End Users/Desktop', + 'License :: OSI Approved :: GNU General Public License (GPL)', + 'Natural Language :: English', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python', + 'Topic :: Software Development :: Libraries :: Python Modules', 'Topic :: System :: Hardware :: Hardware Drivers' ] ) - - for path in [(os.path.join('src', 'calibre', 'gui2', 'pictureflow'))]: - build_PyQt_extension(path) - + if 'develop' in ' '.join(sys.argv) and islinux: subprocess.check_call('calibre_postinstall', shell=True) diff --git a/src/calibre/trac/plugins/templates/distro.html b/src/calibre/trac/plugins/templates/distro.html index 61944e7747..c75532caef 100644 --- a/src/calibre/trac/plugins/templates/distro.html +++ b/src/calibre/trac/plugins/templates/distro.html @@ -14,7 +14,8 @@

      $title

      - See the Changelog for the changes in the latest version. + See the Changelog for the changes in the latest version. Note: As of 0.4.80 this install + will not work on 64-bit CPUs. Try the precompiled binary available here instead.
      First verify that you have a sufficiently new installation of python
      python --version
      should return at least 2.5.1
      diff --git a/src/calibre/trac/plugins/templates/pyinstaller.html b/src/calibre/trac/plugins/templates/pyinstaller.html index 4061b0aadc..901ba16d75 100644 --- a/src/calibre/trac/plugins/templates/pyinstaller.html +++ b/src/calibre/trac/plugins/templates/pyinstaller.html @@ -14,7 +14,7 @@

      Download $app for Linux

      -

      This binary package is compatible with most recent linux distributions running on Intel 32 bit CPUs.

      +

      This binary package is compatible with most recent linux distributions running on Intel 32 bit CPUs. It needs testing on 64 bit CPUs.

      (Version: $version Changelog) diff --git a/upload.py b/upload.py index 4d5dcf5121..6a9f22807b 100644 --- a/upload.py +++ b/upload.py @@ -221,8 +221,8 @@ def stage_one(): os.mkdir('build') shutil.rmtree('docs') os.mkdir('docs') - check_call("sudo python setup.py develop", shell=True) - check_call('sudo rm src/%s/gui2/images_rc.pyc'%__appname__, shell=True) + check_call(['python', 'setup.py', 'build']) + check_call('sudo rm -f src/%s/gui2/images_rc.pyc'%__appname__, shell=True) check_call('make', shell=True) tag_release() upload_demo() @@ -230,7 +230,7 @@ def stage_one(): def stage_two(): subprocess.check_call('rm -rf dist/*', shell=True) build_installers() - build_src_tarball() + build_src_tarball() def stage_three(): print 'Uploading installers...' From 4b22654837e29e06133498e90a7fe89b8d5ee653 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 25 Jul 2008 09:12:21 -0700 Subject: [PATCH 18/34] IGN:... --- installer/linux/freeze.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/installer/linux/freeze.py b/installer/linux/freeze.py index d79d3933d0..7e33ea8be2 100644 --- a/installer/linux/freeze.py +++ b/installer/linux/freeze.py @@ -16,6 +16,7 @@ LIBUNRAR = '/usr/lib/libunrar.so' QTDIR = '/usr/lib/qt4' QTDLLS = ('QtCore', 'QtGui', 'QtNetwork', 'QtSvg', 'QtXml') EXTRAS = ('/usr/lib/python2.5/site-packages/PIL', os.path.expanduser('~/ipython/IPython')) +SQLITE = '/usr/lib/libsqlite3.so.0' CALIBRESRC = os.path.join(CALIBREPREFIX, 'src') @@ -112,6 +113,10 @@ for f in glob.glob(os.path.join(CALIBREPLUGINS, '*.so.*')): print 'Adding external programs...' binaries += [('clit', CLIT, 'BINARY'), ('pdftohtml', PDFTOHTML, 'BINARY'), ('libunrar.so', LIBUNRAR, 'BINARY')] + +print 'Adding external libraries...' +binaries += [(os.path.basename(SQLITE), SQLITE, 'BINARY')] + qt = [] for dll in QTDLLS: path = os.path.join(QTDIR, 'lib'+dll+'.so.4') From 1eba7afa35284fba49addae1594c0ae0751f3555 Mon Sep 17 00:00:00 2001 From: "Marshall T. Vandegrift" Date: Fri, 25 Jul 2008 17:47:30 -0400 Subject: [PATCH 19/34] Fix #908 (Error message when converting LIT file) --- src/calibre/ebooks/lit/reader.py | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/calibre/ebooks/lit/reader.py b/src/calibre/ebooks/lit/reader.py index 3e81e51dbe..a0f87976d7 100644 --- a/src/calibre/ebooks/lit/reader.py +++ b/src/calibre/ebooks/lit/reader.py @@ -92,7 +92,11 @@ def read_utf8_char(bytes, pos): 'Invalid UTF8 character: %s' % repr(bytes[pos:pos+i])) c = (c << 6) | (b & 0x3F) return unichr(c), pos+elsize - + +def consume_utf8_length(bytes): + char, elsize = read_utf8_char(bytes, 0) + return ord(char), bytes[elsize:] + class UnBinary(object): AMPERSAND_RE = re.compile( r'&(?!(?:#[0-9]+|#x[0-9a-fA-F]+|[a-zA-Z_:][a-zA-Z0-9.-_:]+);)') @@ -315,8 +319,11 @@ class ManifestItem(object): self.offset = offset self.root = root self.state = state + # Some LIT files have Windows-style paths + path = original.replace('\\', '/') + if path[1:3] == ':/': path = path[2:] # Some paths in Fictionwise "multiformat" LIT files contain '..' (!?) - path = os.path.normpath(original).replace('\\', '/') + path = os.path.normpath(path).replace('\\', '/') while path.startswith('../'): path = path[3:] self.path = path @@ -557,14 +564,15 @@ class LitReader(object): if len(raw) < 5: raise LitError('Truncated manifest') offset, raw = u32(raw), raw[4:] - slen, raw = ord(raw[0]), raw[1:] + slen, raw = consume_utf8_length(raw) internal, raw = raw[:slen].decode('utf8'), raw[slen:] - slen, raw = ord(raw[0]), raw[1:] + slen, raw = consume_utf8_length(raw) original, raw = raw[:slen].decode('utf8'), raw[slen:] - slen, raw = ord(raw[0]), raw[1:] + slen, raw = consume_utf8_length(raw) mime_type, raw = raw[:slen].decode('utf8'), raw[slen+1:] self.manifest[internal] = ManifestItem( original, internal, mime_type, offset, root, state) + # Remove any common path elements mlist = self.manifest.values() shared = mlist[0].path for item in mlist[1:]: @@ -578,6 +586,10 @@ class LitReader(object): slen = len(shared) for item in mlist: item.path = item.path[slen:] + # Fix any straggling absolute paths + for item in mlist: + if item.path[0] == '/': + item.path = os.path.basename(item.path) def _read_meta(self): raw = self.get_file('/meta') From 41e7844b8b4490903eb75ce51ece6f0c1910b822 Mon Sep 17 00:00:00 2001 From: "Marshall T. Vandegrift" Date: Sat, 26 Jul 2008 00:11:01 -0400 Subject: [PATCH 20/34] Fix #913 (lit2lrf conversion error) --- src/calibre/ebooks/lit/reader.py | 24 ++++++++++++++---------- src/calibre/ebooks/metadata/__init__.py | 2 +- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/calibre/ebooks/lit/reader.py b/src/calibre/ebooks/lit/reader.py index a0f87976d7..a0b170c8fb 100644 --- a/src/calibre/ebooks/lit/reader.py +++ b/src/calibre/ebooks/lit/reader.py @@ -93,9 +93,15 @@ def read_utf8_char(bytes, pos): c = (c << 6) | (b & 0x3F) return unichr(c), pos+elsize -def consume_utf8_length(bytes): - char, elsize = read_utf8_char(bytes, 0) - return ord(char), bytes[elsize:] +def consume_sized_utf8_string(bytes, zpad=False): + result = [] + slen, pos = read_utf8_char(bytes, 0) + for i in xrange(ord(slen)): + char, pos = read_utf8_char(bytes, pos) + result.append(char) + if zpad and bytes[pos] == '\000': + pos += 1 + return u''.join(result), bytes[pos:] class UnBinary(object): AMPERSAND_RE = re.compile( @@ -519,7 +525,7 @@ class LitReader(object): raise LitError('Directory entry had 64bit name length.') if namelen > remaining - 3: raise LitError('Read past end of directory chunk') - name, chunk = chunk[:namelen], chunk[namelen:] + name, chunk = chunk[:namelen].decode('utf-8'), chunk[namelen:] section, chunk, remaining = encint(chunk, remaining) offset, chunk, remaining = encint(chunk, remaining) size, chunk, remaining = encint(chunk, remaining) @@ -564,12 +570,10 @@ class LitReader(object): if len(raw) < 5: raise LitError('Truncated manifest') offset, raw = u32(raw), raw[4:] - slen, raw = consume_utf8_length(raw) - internal, raw = raw[:slen].decode('utf8'), raw[slen:] - slen, raw = consume_utf8_length(raw) - original, raw = raw[:slen].decode('utf8'), raw[slen:] - slen, raw = consume_utf8_length(raw) - mime_type, raw = raw[:slen].decode('utf8'), raw[slen+1:] + internal, raw = consume_sized_utf8_string(raw) + original, raw = consume_sized_utf8_string(raw) + # Is this last one UTF-8 or ASCIIZ? + mime_type, raw = consume_sized_utf8_string(raw, zpad=True) self.manifest[internal] = ManifestItem( original, internal, mime_type, offset, root, state) # Remove any common path elements diff --git a/src/calibre/ebooks/metadata/__init__.py b/src/calibre/ebooks/metadata/__init__.py index e4fb42cc95..413e284794 100644 --- a/src/calibre/ebooks/metadata/__init__.py +++ b/src/calibre/ebooks/metadata/__init__.py @@ -65,7 +65,7 @@ class Resource(object): else: pc = url[2] if isinstance(pc, unicode): - pc.encode('utf-8') + pc = pc.encode('utf-8') pc = unquote(pc).decode('utf-8') self.path = os.path.abspath(os.path.join(basedir, pc.replace('/', os.sep))) self.fragment = unquote(url[-1]) From e67eca948764944ccc1d1d3ae2bf46192bff5954 Mon Sep 17 00:00:00 2001 From: "Marshall T. Vandegrift" Date: Sat, 26 Jul 2008 07:56:39 -0400 Subject: [PATCH 21/34] Fix #416 (Error converting .lit file) --- src/calibre/ebooks/lit/reader.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/calibre/ebooks/lit/reader.py b/src/calibre/ebooks/lit/reader.py index a0b170c8fb..683f8d8dad 100644 --- a/src/calibre/ebooks/lit/reader.py +++ b/src/calibre/ebooks/lit/reader.py @@ -576,20 +576,21 @@ class LitReader(object): mime_type, raw = consume_sized_utf8_string(raw, zpad=True) self.manifest[internal] = ManifestItem( original, internal, mime_type, offset, root, state) - # Remove any common path elements mlist = self.manifest.values() - shared = mlist[0].path - for item in mlist[1:]: - path = item.path - while shared and not path.startswith(shared): - try: shared = shared[:shared.rindex("/", 0, -2) + 1] - except ValueError: shared = None - if not shared: - break - if shared: - slen = len(shared) - for item in mlist: - item.path = item.path[slen:] + # Remove any common path elements + if len(mlist) > 1: + shared = mlist[0].path + for item in mlist[1:]: + path = item.path + while shared and not path.startswith(shared): + try: shared = shared[:shared.rindex("/", 0, -2) + 1] + except ValueError: shared = None + if not shared: + break + if shared: + slen = len(shared) + for item in mlist: + item.path = item.path[slen:] # Fix any straggling absolute paths for item in mlist: if item.path[0] == '/': From e9ba420cfc46b61eb8ea96f360b6e08850cf6b6f Mon Sep 17 00:00:00 2001 From: "Marshall T. Vandegrift" Date: Sat, 26 Jul 2008 14:19:26 -0400 Subject: [PATCH 22/34] Converted DES decryption to a Python/C module --- setup.py | 6 +- src/calibre/__init__.py | 2 +- src/calibre/ebooks/lit/reader.py | 9 +- src/calibre/utils/msdes/d3des.h | 156 ++++++ src/calibre/utils/msdes/des.c | 693 ++++++++++++++++++++++++++ src/calibre/utils/msdes/msdesmodule.c | 98 ++++ src/calibre/utils/msdes/spr.h | 202 ++++++++ 7 files changed, 1160 insertions(+), 6 deletions(-) create mode 100644 src/calibre/utils/msdes/d3des.h create mode 100644 src/calibre/utils/msdes/des.c create mode 100644 src/calibre/utils/msdes/msdesmodule.c create mode 100644 src/calibre/utils/msdes/spr.h diff --git a/setup.py b/setup.py index 03cd53efe5..9150a28b90 100644 --- a/setup.py +++ b/setup.py @@ -53,7 +53,11 @@ if __name__ == '__main__': ext_modules = [Extension('calibre.plugins.lzx', sources=['src/calibre/utils/lzx/lzxmodule.c', 'src/calibre/utils/lzx/lzxd.c'], - include_dirs=['src/calibre/utils/lzx'])] + include_dirs=['src/calibre/utils/lzx']), + Extension('calibre.plugins.msdes', + sources=['src/calibre/utils/msdes/msdesmodule.c', + 'src/calibre/utils/msdes/des.c'], + include_dirs=['src/calibre/utils/msdes'])] if iswindows: ext_modules.append(Extension('calibre.plugins.winutil', sources=['src/calibre/utils/windows/winutil.c'], diff --git a/src/calibre/__init__.py b/src/calibre/__init__.py index 65f1151e46..be12f3d102 100644 --- a/src/calibre/__init__.py +++ b/src/calibre/__init__.py @@ -61,7 +61,7 @@ if iswindows and getattr(sys, 'frozen', False): plugins = {} -for plugin in ['pictureflow', 'lzx'] + \ +for plugin in ['pictureflow', 'lzx', 'msdes'] + \ (['winutil'] if iswindows else []) + \ (['usbobserver'] if isosx else []): try: diff --git a/src/calibre/ebooks/lit/reader.py b/src/calibre/ebooks/lit/reader.py index 683f8d8dad..4fb5280a4d 100644 --- a/src/calibre/ebooks/lit/reader.py +++ b/src/calibre/ebooks/lit/reader.py @@ -13,9 +13,9 @@ import re from calibre.ebooks.lit import LitError from calibre.ebooks.lit.maps import OPF_MAP, HTML_MAP import calibre.ebooks.lit.mssha1 as mssha1 -import calibre.ebooks.lit.msdes as msdes from calibre import plugins lzx, lxzerror = plugins['lzx'] +msdes, msdeserror = plugins['msdes'] OPF_DECL = """ > 3] & bytebit[m]) ? 1 : 0; + } + for( i = 0; i < 16; i++ ) { + if( edf == DE1 ) m = (15 - i) << 1; + else m = i << 1; + n = m + 1; + kn[m] = kn[n] = 0L; + for( j = 0; j < 28; j++ ) { + l = j + totrot[i]; + if( l < 28 ) pcr[j] = pc1m[l]; + else pcr[j] = pc1m[l - 28]; + } + for( j = 28; j < 56; j++ ) { + l = j + totrot[i]; + if( l < 56 ) pcr[j] = pc1m[l]; + else pcr[j] = pc1m[l - 28]; + } + for( j = 0; j < 24; j++ ) { + if( pcr[pc2[j]] ) kn[m] |= bigbyte[j]; + if( pcr[pc2[j+24]] ) kn[n] |= bigbyte[j]; + } + } + cookey(kn); + return; + } + +static void cookey(raw1) +unsigned long *raw1; +{ + unsigned long *cook, *raw0; + unsigned long dough[32]; + int i; + + cook = dough; + for( i = 0; i < 16; i++, raw1++ ) { + raw0 = raw1++; + *cook = (*raw0 & 0x00fc0000L) << 6; + *cook |= (*raw0 & 0x00000fc0L) << 10; + *cook |= (*raw1 & 0x00fc0000L) >> 10; + *cook++ |= (*raw1 & 0x00000fc0L) >> 6; + *cook = (*raw0 & 0x0003f000L) << 12; + *cook |= (*raw0 & 0x0000003fL) << 16; + *cook |= (*raw1 & 0x0003f000L) >> 4; + *cook++ |= (*raw1 & 0x0000003fL); + } + usekey(dough); + return; + } + +void cpkey(into) +unsigned long *into; +{ + unsigned long *from, *endp; + + from = KnL, endp = &KnL[32]; + while( from < endp ) *into++ = *from++; + return; + } + +void usekey(from) +unsigned long *from; +{ + unsigned long *to, *endp; + + to = KnL, endp = &KnL[32]; + while( to < endp ) *to++ = *from++; + return; + } + +void des(inblock, outblock) +unsigned char *inblock, *outblock; +{ + unsigned long work[2]; + + scrunch(inblock, work); + desfunc(work, KnL); + unscrun(work, outblock); + return; + } + + +static void scrunch(outof, into) +unsigned char *outof; +unsigned long *into; +{ + *into = (*outof++ & 0xffL) << 24; + *into |= (*outof++ & 0xffL) << 16; + *into |= (*outof++ & 0xffL) << 8; + *into++ |= (*outof++ & 0xffL); + *into = (*outof++ & 0xffL) << 24; + *into |= (*outof++ & 0xffL) << 16; + *into |= (*outof++ & 0xffL) << 8; + *into |= (*outof & 0xffL); + return; + } + + +static void unscrun(outof, into) +unsigned long *outof; +unsigned char *into; +{ + *into++ = (*outof >> 24) & 0xffL; + *into++ = (*outof >> 16) & 0xffL; + *into++ = (*outof >> 8) & 0xffL; + *into++ = *outof++ & 0xffL; + *into++ = (*outof >> 24) & 0xffL; + *into++ = (*outof >> 16) & 0xffL; + *into++ = (*outof >> 8) & 0xffL; + *into = *outof & 0xffL; + return; + } + +#include "spr.h" +/* +static unsigned long SP1[64] = { + 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L, + 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L, + 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L, + 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L, + 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L, + 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L, + 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L, + 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L, + 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L, + 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L, + 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L, + 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L, + 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L, + 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L, + 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L, + 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L }; + +static unsigned long SP2[64] = { + 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L, + 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L, + 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L, + 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L, + 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L, + 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L, + 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L, + 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L, + 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L, + 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L, + 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L, + 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L, + 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L, + 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L, + 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L, + 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L }; + +static unsigned long SP3[64] = { + 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L, + 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L, + 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L, + 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L, + 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L, + 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L, + 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L, + 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L, + 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L, + 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L, + 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L, + 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L, + 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L, + 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L, + 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L, + 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L }; + +static unsigned long SP4[64] = { + 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, + 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L, + 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L, + 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L, + 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L, + 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L, + 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L, + 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L, + 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L, + 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L, + 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L, + 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, + 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L, + 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L, + 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L, + 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L }; + +static unsigned long SP5[64] = { + 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L, + 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L, + 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L, + 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L, + 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L, + 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L, + 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L, + 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L, + 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L, + 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L, + 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L, + 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L, + 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L, + 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L, + 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L, + 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L }; + +static unsigned long SP6[64] = { + 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L, + 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L, + 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L, + 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L, + 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L, + 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L, + 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L, + 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L, + 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L, + 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L, + 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L, + 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L, + 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L, + 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L, + 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L, + 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L }; + +static unsigned long SP7[64] = { + 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L, + 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L, + 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L, + 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L, + 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L, + 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L, + 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L, + 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L, + 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L, + 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L, + 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L, + 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L, + 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L, + 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L, + 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L, + 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L }; + +static unsigned long SP8[64] = { + 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L, + 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L, + 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L, + 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L, + 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L, + 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L, + 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L, + 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L, + 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L, + 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L, + 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L, + 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L, + 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L, + 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L, + 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L, + 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L }; +*/ + + +static void desfunc(block, keys) +unsigned long *block, *keys; +{ + unsigned long fval, work, right, leftt; + int round; + + leftt = block[0]; + right = block[1]; + work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL; + right ^= work; + leftt ^= (work << 4); + work = ((leftt >> 16) ^ right) & 0x0000ffffL; + right ^= work; + leftt ^= (work << 16); + work = ((right >> 2) ^ leftt) & 0x33333333L; + leftt ^= work; + right ^= (work << 2); + work = ((right >> 8) ^ leftt) & 0x00ff00ffL; + leftt ^= work; + right ^= (work << 8); + right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL; + work = (leftt ^ right) & 0xaaaaaaaaL; + leftt ^= work; + right ^= work; + leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL; + + for( round = 0; round < 8; round++ ) { + work = (right << 28) | (right >> 4); + work ^= *keys++; + fval = SP7[ work & 0x3fL]; + fval |= SP5[(work >> 8) & 0x3fL]; + fval |= SP3[(work >> 16) & 0x3fL]; + fval |= SP1[(work >> 24) & 0x3fL]; + work = right ^ *keys++; + fval |= SP8[ work & 0x3fL]; + fval |= SP6[(work >> 8) & 0x3fL]; + fval |= SP4[(work >> 16) & 0x3fL]; + fval |= SP2[(work >> 24) & 0x3fL]; + leftt ^= fval; + work = (leftt << 28) | (leftt >> 4); + work ^= *keys++; + fval = SP7[ work & 0x3fL]; + fval |= SP5[(work >> 8) & 0x3fL]; + fval |= SP3[(work >> 16) & 0x3fL]; + fval |= SP1[(work >> 24) & 0x3fL]; + work = leftt ^ *keys++; + fval |= SP8[ work & 0x3fL]; + fval |= SP6[(work >> 8) & 0x3fL]; + fval |= SP4[(work >> 16) & 0x3fL]; + fval |= SP2[(work >> 24) & 0x3fL]; + right ^= fval; + } + + right = (right << 31) | (right >> 1); + work = (leftt ^ right) & 0xaaaaaaaaL; + leftt ^= work; + right ^= work; + leftt = (leftt << 31) | (leftt >> 1); + work = ((leftt >> 8) ^ right) & 0x00ff00ffL; + right ^= work; + leftt ^= (work << 8); + work = ((leftt >> 2) ^ right) & 0x33333333L; + right ^= work; + leftt ^= (work << 2); + work = ((right >> 16) ^ leftt) & 0x0000ffffL; + leftt ^= work; + right ^= (work << 16); + work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL; + leftt ^= work; + right ^= (work << 4); + *block++ = right; + *block = leftt; + return; + } + +#ifdef D2_DES + +void des2key(hexkey, mode) /* stomps on Kn3 too */ +unsigned char *hexkey; /* unsigned char[16] */ +short mode; +{ + short revmod; + + revmod = (mode == EN0) ? DE1 : EN0; + deskey(&hexkey[8], revmod); + cpkey(KnR); + deskey(hexkey, mode); + cpkey(Kn3); /* Kn3 = KnL */ + return; + } + +void Ddes(from, into) +unsigned char *from, *into; /* unsigned char[8] */ +{ + unsigned long work[2]; + + scrunch(from, work); + desfunc(work, KnL); + desfunc(work, KnR); + desfunc(work, Kn3); + unscrun(work, into); + return; + } + +void D2des(from, into) +unsigned char *from; /* unsigned char[16] */ +unsigned char *into; /* unsigned char[16] */ +{ + unsigned long *right, *l1, swap; + unsigned long leftt[2], bufR[2]; + + right = bufR; + l1 = &leftt[1]; + scrunch(from, leftt); + scrunch(&from[8], right); + desfunc(leftt, KnL); + desfunc(right, KnL); + swap = *l1; + *l1 = *right; + *right = swap; + desfunc(leftt, KnR); + desfunc(right, KnR); + swap = *l1; + *l1 = *right; + *right = swap; + desfunc(leftt, Kn3); + desfunc(right, Kn3); + unscrun(leftt, into); + unscrun(right, &into[8]); + return; + } + +void makekey(aptr, kptr) +char *aptr; /* NULL-terminated */ +unsigned char *kptr; /* unsigned char[8] */ +{ + unsigned char *store; + int first, i; + unsigned long savek[96]; + + cpDkey(savek); + des2key(Df_Key, EN0); + for( i = 0; i < 8; i++ ) kptr[i] = Df_Key[i]; + first = 1; + while( (*aptr != '\0') || first ) { + store = kptr; + for( i = 0; i < 8 && (*aptr != '\0'); i++ ) { + *store++ ^= *aptr & 0x7f; + *aptr++ = '\0'; + } + Ddes(kptr, kptr); + first = 0; + } + useDkey(savek); + return; + } + +void make2key(aptr, kptr) +char *aptr; /* NULL-terminated */ +unsigned char *kptr; /* unsigned char[16] */ +{ + unsigned char *store; + int first, i; + unsigned long savek[96]; + + cpDkey(savek); + des2key(Df_Key, EN0); + for( i = 0; i < 16; i++ ) kptr[i] = Df_Key[i]; + first = 1; + while( (*aptr != '\0') || first ) { + store = kptr; + for( i = 0; i < 16 && (*aptr != '\0'); i++ ) { + *store++ ^= *aptr & 0x7f; + *aptr++ = '\0'; + } + D2des(kptr, kptr); + first = 0; + } + useDkey(savek); + return; + } + +#ifndef D3_DES /* D2_DES only */ + +void cp2key(into) +unsigned long *into; /* unsigned long[64] */ +{ + unsigned long *from, *endp; + + cpkey(into); + into = &into[32]; + from = KnR, endp = &KnR[32]; + while( from < endp ) *into++ = *from++; + return; + } + +void use2key(from) /* stomps on Kn3 too */ +unsigned long *from; /* unsigned long[64] */ +{ + unsigned long *to, *endp; + + usekey(from); + from = &from[32]; + to = KnR, endp = &KnR[32]; + while( to < endp ) *to++ = *from++; + cpkey(Kn3); /* Kn3 = KnL */ + return; + } + +#else /* D3_DES too */ + +void des3key(hexkey, mode) +unsigned char *hexkey; /* unsigned char[24] */ +short mode; +{ + unsigned char *first, *third; + short revmod; + + if( mode == EN0 ) { + revmod = DE1; + first = hexkey; + third = &hexkey[16]; + } + else { + revmod = EN0; + first = &hexkey[16]; + third = hexkey; + } + deskey(&hexkey[8], revmod); + cpkey(KnR); + deskey(third, mode); + cpkey(Kn3); + deskey(first, mode); + return; + } + +void cp3key(into) +unsigned long *into; /* unsigned long[96] */ +{ + unsigned long *from, *endp; + + cpkey(into); + into = &into[32]; + from = KnR, endp = &KnR[32]; + while( from < endp ) *into++ = *from++; + from = Kn3, endp = &Kn3[32]; + while( from < endp ) *into++ = *from++; + return; + } + +void use3key(from) +unsigned long *from; /* unsigned long[96] */ +{ + unsigned long *to, *endp; + + usekey(from); + from = &from[32]; + to = KnR, endp = &KnR[32]; + while( to < endp ) *to++ = *from++; + to = Kn3, endp = &Kn3[32]; + while( to < endp ) *to++ = *from++; + return; + } + +static void D3des(unsigned char *, unsigned char *); + +static void D3des(from, into) /* amateur theatrics */ +unsigned char *from; /* unsigned char[24] */ +unsigned char *into; /* unsigned char[24] */ +{ + unsigned long swap, leftt[2], middl[2], right[2]; + + scrunch(from, leftt); + scrunch(&from[8], middl); + scrunch(&from[16], right); + desfunc(leftt, KnL); + desfunc(middl, KnL); + desfunc(right, KnL); + swap = leftt[1]; + leftt[1] = middl[0]; + middl[0] = swap; + swap = middl[1]; + middl[1] = right[0]; + right[0] = swap; + desfunc(leftt, KnR); + desfunc(middl, KnR); + desfunc(right, KnR); + swap = leftt[1]; + leftt[1] = middl[0]; + middl[0] = swap; + swap = middl[1]; + middl[1] = right[0]; + right[0] = swap; + desfunc(leftt, Kn3); + desfunc(middl, Kn3); + desfunc(right, Kn3); + unscrun(leftt, into); + unscrun(middl, &into[8]); + unscrun(right, &into[16]); + return; + } + +void make3key(aptr, kptr) +char *aptr; /* NULL-terminated */ +unsigned char *kptr; /* unsigned char[24] */ +{ + unsigned char *store; + int first, i; + unsigned long savek[96]; + + cp3key(savek); + des3key(Df_Key, EN0); + for( i = 0; i < 24; i++ ) kptr[i] = Df_Key[i]; + first = 1; + while( (*aptr != '\0') || first ) { + store = kptr; + for( i = 0; i < 24 && (*aptr != '\0'); i++ ) { + *store++ ^= *aptr & 0x7f; + *aptr++ = '\0'; + } + D3des(kptr, kptr); + first = 0; + } + use3key(savek); + return; + } + +#endif /* D3_DES */ +#endif /* D2_DES */ + +/* Validation sets: + * + * Single-length key, single-length plaintext - + * Key : 0123 4567 89ab cdef + * Plain : 0123 4567 89ab cde7 + * Cipher : c957 4425 6a5e d31d + * + * Double-length key, single-length plaintext - + * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 + * Plain : 0123 4567 89ab cde7 + * Cipher : 7f1d 0a77 826b 8aff + * + * Double-length key, double-length plaintext - + * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 + * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff + * Cipher : 27a0 8440 406a df60 278f 47cf 42d6 15d7 + * + * Triple-length key, single-length plaintext - + * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567 + * Plain : 0123 4567 89ab cde7 + * Cipher : de0b 7c06 ae5e 0ed5 + * + * Triple-length key, double-length plaintext - + * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567 + * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff + * Cipher : ad0d 1b30 ac17 cf07 0ed1 1c63 81e4 4de5 + * + * d3des V5.09 rwo 9208.04 20:31 Graven Imagery + **********************************************************************/ + diff --git a/src/calibre/utils/msdes/msdesmodule.c b/src/calibre/utils/msdes/msdesmodule.c new file mode 100644 index 0000000000..27ca46ffcb --- /dev/null +++ b/src/calibre/utils/msdes/msdesmodule.c @@ -0,0 +1,98 @@ +/* __license__ = 'GPL v3' + * __copyright__ = '2008, Marshall T. Vandegrift ' + * + * Python module C glue code. + */ + + +#include + +#include + +static char msdes_doc[] = +"Provide LIT-specific DES en/decryption."; + +static PyObject *MsDesError = NULL; + +static PyObject * +msdes_deskey(PyObject *self, PyObject *args) +{ + unsigned char *key = NULL; + unsigned int len = 0; + short int edf = 0; + + if (!PyArg_ParseTuple(args, "s#h", &key, &len, &edf)) { + return NULL; + } + + if (len != 8) { + PyErr_SetString(MsDesError, "Key length incorrect"); + return NULL; + } + + if ((edf != EN0) && (edf != DE1)) { + PyErr_SetString(MsDesError, "En/decryption direction invalid"); + return NULL; + } + + deskey(key, edf); + + Py_RETURN_NONE; +} + +static PyObject * +msdes_des(PyObject *self, PyObject *args) +{ + unsigned char *inbuf = NULL; + unsigned char *outbuf = NULL; + unsigned int len = 0; + unsigned int off = 0; + PyObject *retval = NULL; + + if (!PyArg_ParseTuple(args, "s#", &inbuf, &len)) { + return NULL; + } + + if ((len == 0) || ((len % 8) != 0)) { + PyErr_SetString(MsDesError, + "Input length not a multiple of the block size"); + return NULL; + } + + retval = PyString_FromStringAndSize(NULL, len); + if (retval == NULL) { + return NULL; + } + outbuf = (unsigned char *)PyString_AS_STRING(retval); + + for (off = 0; off < len; off += 8) { + des((inbuf + off), (outbuf + off)); + } + + return retval; +} + +static PyMethodDef msdes_methods[] = { + { "deskey", &msdes_deskey, METH_VARARGS, "Provide a new key for DES en/decryption." }, + { "des", &msdes_des, METH_VARARGS, "Perform DES en/decryption." }, + { NULL, NULL } +}; + +PyMODINIT_FUNC +initmsdes(void) +{ + PyObject *m; + + m = Py_InitModule3("msdes", msdes_methods, msdes_doc); + if (m == NULL) { + return; + } + + MsDesError = PyErr_NewException("msdes.MsDesError", NULL, NULL); + Py_INCREF(MsDesError); + PyModule_AddObject(m, "MsDesError", MsDesError); + PyModule_AddObject(m, "EN0", PyInt_FromLong(EN0)); + PyModule_AddObject(m, "DE1", PyInt_FromLong(DE1)); + + return; +} diff --git a/src/calibre/utils/msdes/spr.h b/src/calibre/utils/msdes/spr.h new file mode 100644 index 0000000000..fdcf5e3e46 --- /dev/null +++ b/src/calibre/utils/msdes/spr.h @@ -0,0 +1,202 @@ +/* crypto/des/spr.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +static unsigned long SP1[64] = { +0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L, +0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L, +0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L, +0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L, +0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L, +0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L, +0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L, +0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L, +0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L, +0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L, +0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L, +0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L, +0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L, +0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L, +0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L, +0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L +}; +static unsigned long SP2[64] = { +0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L, +0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L, +0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L, +0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L, +0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L, +0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L, +0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L, +0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L, +0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L, +0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L, +0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L, +0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L, +0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L, +0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L, +0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L, +0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L +}; +static unsigned long SP3[64] = { +0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L, +0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L, +0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L, +0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L, +0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L, +0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L, +0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L, +0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L, +0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L, +0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L, +0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L, +0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L, +0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L, +0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L, +0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L, +0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L +}; +static unsigned long SP4[64] = { +0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L, +0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L, +0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L, +0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L, +0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L, +0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L, +0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L, +0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L, +0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L, +0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L, +0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L, +0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L, +0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L, +0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L, +0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L, +0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L +}; +static unsigned long SP5[64] = { +0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L, +0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L, +0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L, +0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L, +0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L, +0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L, +0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L, +0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L, +0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L, +0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L, +0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L, +0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L, +0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L, +0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L, +0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L, +0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L +}; +static unsigned long SP6[64] = { +0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L, +0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L, +0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L, +0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L, +0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L, +0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L, +0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L, +0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L, +0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L, +0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L, +0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L, +0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L, +0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L, +0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L, +0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L, +0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L, +}; +static unsigned long SP7[64] = { +0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L, +0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L, +0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L, +0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L, +0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L, +0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L, +0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L, +0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L, +0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L, +0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L, +0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L, +0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L, +0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L, +0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L, +0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L, +0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L, +}; +static unsigned long SP8[64] = { +0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L, +0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L, +0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L, +0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L, +0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L, +0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L, +0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L, +0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L, +0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L, +0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L, +0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L, +0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L, +0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L, +0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L, +0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L, +0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L, +}; From ac819eec9d600cc2687cb2e86d0cefd8d7f6d0ea Mon Sep 17 00:00:00 2001 From: "Marshall T. Vandegrift" Date: Sat, 26 Jul 2008 14:56:07 -0400 Subject: [PATCH 23/34] Convert some range()s to xrange()s --- src/calibre/ebooks/lit/reader.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/calibre/ebooks/lit/reader.py b/src/calibre/ebooks/lit/reader.py index 4fb5280a4d..cb33505d75 100644 --- a/src/calibre/ebooks/lit/reader.py +++ b/src/calibre/ebooks/lit/reader.py @@ -85,7 +85,7 @@ def read_utf8_char(bytes, pos): if elsize + pos > len(bytes): raise LitError('Invalid UTF8 character: %s' % repr(bytes[pos])) c &= (mask - 1) - for i in range(1, elsize): + for i in xrange(1, elsize): b = ord(bytes[pos+i]) if (b & 0xC0) != 0x80: raise LitError( @@ -475,7 +475,7 @@ class LitReader(object): def _read_header_pieces(self): src = self.header[self.hdr_len:] - for i in range(self.num_pieces): + for i in xrange(self.num_pieces): piece = src[i * self.PIECE_SIZE:(i + 1) * self.PIECE_SIZE] if u32(piece[4:]) != 0 or u32(piece[12:]) != 0: raise LitError('Piece %s has 64bit value' % repr(piece)) @@ -542,7 +542,7 @@ class LitReader(object): self.num_sections = u16(raw[2:pos]) self.section_names = [""]*self.num_sections self.section_data = [None]*self.num_sections - for section in range(self.num_sections): + for section in xrange(self.num_sections): size = u16(raw[pos:pos+2]) pos += 2 size = size*2 + 2 From 97b5fc46ba58d20e0ad919cd9a8d2c8e9160efc2 Mon Sep 17 00:00:00 2001 From: "Marshall T. Vandegrift" Date: Sat, 26 Jul 2008 15:53:26 -0400 Subject: [PATCH 24/34] Use pysco when UnBinarying, if available --- src/calibre/ebooks/lit/reader.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/calibre/ebooks/lit/reader.py b/src/calibre/ebooks/lit/reader.py index cb33505d75..d9924a2454 100644 --- a/src/calibre/ebooks/lit/reader.py +++ b/src/calibre/ebooks/lit/reader.py @@ -797,5 +797,12 @@ def main(args=sys.argv): print _('OEB ebook created in'), opts.output_dir return 0 +try: + import psyco + psyco.bind(read_utf8_char) + psyco.bind(UnBinary.binary_to_text) +except ImportError: + pass + if __name__ == '__main__': sys.exit(main()) From 49e8e8b4b280b200ac56cc18dd71a9d4114c9fc0 Mon Sep 17 00:00:00 2001 From: "Marshall T. Vandegrift" Date: Sat, 26 Jul 2008 16:00:37 -0400 Subject: [PATCH 25/34] Removed pure-Python LIT-specific DES code --- src/calibre/ebooks/lit/msdes.py | 489 -------------------------------- 1 file changed, 489 deletions(-) delete mode 100644 src/calibre/ebooks/lit/msdes.py diff --git a/src/calibre/ebooks/lit/msdes.py b/src/calibre/ebooks/lit/msdes.py deleted file mode 100644 index de980f8c3d..0000000000 --- a/src/calibre/ebooks/lit/msdes.py +++ /dev/null @@ -1,489 +0,0 @@ -# Re-modified for use in MS LIT decryption. Un-reversed the bytebit[] array. -# Substituted Microsoft's absurd modified S-boxes. Modified the -# encrypt/decrypt methods to handle more than one block at a time. Added a few -# speed-ups supported by modern versions of Python. Added option 'psyco' use. -# -# And lo, all the previous notices follow: - -# Modified DES encryption for VNC password authentication. -# Ported from realvnc's java viewer by -# I chose this package name because it is not compatible with the -# original DES algorithm, e.g. found pycrypto. -# -# (C) 2003 chris -# Released as free software under the Python License. -# -# You're free to use it for commercial and noncommercial -# application, modify and redistribute it as long as the -# copyright notices are intact. There are no warranties, not -# even that it does what it says to do ;-) -# -# Original notice following: - -# This DES class has been extracted from package Acme.Crypto for use in VNC. -# The bytebit[] array has been reversed so that the most significant bit -# in each byte of the key is ignored, not the least significant. Also the -# unnecessary odd parity code has been removed. -# -# These changes are: -# Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. -# -# This software is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# - -# DesCipher - the DES encryption method -# -# The meat of this code is by Dave Zimmerman , and is: -# -# Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved. -# -# Permission to use, copy, modify, and distribute this software -# and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and -# without fee is hereby granted, provided that this copyright notice is kept -# intact. -# -# WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY -# OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -# TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -# PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE LIABLE -# FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR -# DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. -# -# THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE -# CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE -# PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT -# NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE -# SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE -# SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE -# PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). WIDGET WORKSHOP -# SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR -# HIGH RISK ACTIVITIES. -# -# -# The rest is: -# -# Copyright (C) 1996 by Jef Poskanzer . All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# Visit the ACME Labs Java page for up-to-date versions of this and other -# fine Java utilities: http://www.acme.com/java/ - - -#/ The DES encryption method. -#

      -# This is surprisingly fast, for pure Java. On a SPARC 20, wrapped -# in Acme.Crypto.EncryptedOutputStream or Acme.Crypto.EncryptedInputStream, -# it does around 7000 bytes/second. -#

      -# Most of this code is by Dave Zimmerman , and is -# Copyright (c) 1996 Widget Workshop, Inc. See the source file for details. -#

      -# Fetch the software.
      -# Fetch the entire Acme package. -#

      -# @see Des3Cipher -# @see EncryptedOutputStream -# @see EncryptedInputStream - -import struct - -class DesCipher: - # Constructor, byte-array key. - def __init__(self, key): - self.setKey(key) - - #/ Set the key. - def setKey(self, key): - self.encryptKeys = self.deskey([ord(x) for x in key], 1) - self.decryptKeys = self.deskey([ord(x) for x in key], 0) - - # Turn an 8-byte key into internal keys. - def deskey(self, keyBlock, encrypting): - #~ int i, j, l, m, n; - pc1m = [0]*56 #new int[56]; - pcr = [0]*56 #new int[56]; - kn = [0]*32 #new int[32]; - - for j in xrange(56): - l = pc1[j] - m = l & 07 - pc1m[j] = ((keyBlock[l >> 3] & bytebit[m]) != 0) - for i in xrange(16): - if encrypting: - m = i << 1 - else: - m = (15-i) << 1 - n = m + 1 - kn[m] = kn[n] = 0 - for j in xrange(28): - l = j + totrot[i] - if l < 28: - pcr[j] = pc1m[l] - else: - pcr[j] = pc1m[l - 28] - for j in xrange(28, 56): - l = j + totrot[i] - if l < 56: - pcr[j] = pc1m[l] - else: - pcr[j] = pc1m[l - 28] - for j in xrange(24): - if pcr[pc2[j]] != 0: - kn[m] |= bigbyte[j] - if pcr[pc2[j+24]] != 0: - kn[n] |= bigbyte[j] - return self.cookey(kn) - - def cookey(self, raw): - #~ int raw0, raw1; - #~ int rawi, KnLi; - #~ int i; - KnL = [0]*32 - - rawi = 0 - KnLi = 0 - for i in xrange(16): - raw0 = raw[rawi] - rawi += 1 - raw1 = raw[rawi] - rawi += 1 - KnL[KnLi] = (raw0 & 0x00fc0000L) << 6 - KnL[KnLi] |= (raw0 & 0x00000fc0L) << 10 - KnL[KnLi] |= (raw1 & 0x00fc0000L) >> 10 - KnL[KnLi] |= (raw1 & 0x00000fc0L) >> 6 - KnLi += 1 - KnL[KnLi] = (raw0 & 0x0003f000L) << 12 - KnL[KnLi] |= (raw0 & 0x0000003fL) << 16 - KnL[KnLi] |= (raw1 & 0x0003f000L) >> 4 - KnL[KnLi] |= (raw1 & 0x0000003fL) - KnLi += 1 - return KnL - - # Block encryption routines. - - #/ Encrypt a block of eight bytes. - def encrypt(self, clearText): - if len(clearText) % 8 != 0: - raise TypeError, "length must be multiple of block size" - result = [] - for base in xrange(0, len(clearText), 8): - result.append(struct.pack( - ">LL", *self.des(struct.unpack(">LL", clearText[base:base+8]), - self.encryptKeys))) - return ''.join(result) - - #/ Decrypt a block of eight bytes. - def decrypt(self, cipherText): - if len(cipherText) % 8 != 0: - raise TypeError, "length must be multiple of block size" - result = [] - for base in xrange(0, len(cipherText), 8): - result.append(struct.pack( - ">LL", *self.des(struct.unpack(">LL", cipherText[base:base+8]), - self.decryptKeys))) - return ''.join(result) - - # The DES function. - def des(self, (leftt, right), keys): - #~ int fval, work, right, leftt; - #~ int round - keysi = 0 - - work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL - right ^= work - leftt ^= (work << 4) & 0xffffffffL - - work = ((leftt >> 16) ^ right) & 0x0000ffffL - right ^= work - leftt ^= (work << 16) & 0xffffffffL - - work = ((right >> 2) ^ leftt) & 0x33333333L - leftt ^= work - right ^= (work << 2) & 0xffffffffL - - work = ((right >> 8) ^ leftt) & 0x00ff00ffL - leftt ^= work - right ^= (work << 8) & 0xffffffffL - right = ((right << 1) | ((right >> 31) & 1)) & 0xffffffffL - - work = (leftt ^ right) & 0xaaaaaaaaL - leftt ^= work - right ^= work - leftt = ((leftt << 1) | ((leftt >> 31) & 1)) & 0xffffffffL - - for round in xrange(8): - work = ((right << 28) | (right >> 4)) & 0xffffffffL - work ^= keys[keysi] - keysi += 1 - fval = SP7[ work & 0x0000003fL ] - fval |= SP5[(work >> 8) & 0x0000003fL ] - fval |= SP3[(work >> 16) & 0x0000003fL ] - fval |= SP1[(work >> 24) & 0x0000003fL ] - work = right ^ keys[keysi] - keysi += 1 - fval |= SP8[ work & 0x0000003fL ] - fval |= SP6[(work >> 8) & 0x0000003fL ] - fval |= SP4[(work >> 16) & 0x0000003fL ] - fval |= SP2[(work >> 24) & 0x0000003fL ] - leftt ^= fval - work = ((leftt << 28) | (leftt >> 4)) & 0xffffffffL - work ^= keys[keysi] - keysi += 1 - fval = SP7[ work & 0x0000003fL ] - fval |= SP5[(work >> 8) & 0x0000003fL ] - fval |= SP3[(work >> 16) & 0x0000003fL ] - fval |= SP1[(work >> 24) & 0x0000003fL ] - work = leftt ^ keys[keysi] - keysi += 1 - fval |= SP8[ work & 0x0000003fL ] - fval |= SP6[(work >> 8) & 0x0000003fL ] - fval |= SP4[(work >> 16) & 0x0000003fL ] - fval |= SP2[(work >> 24) & 0x0000003fL ] - right ^= fval - - right = ((right << 31) | (right >> 1)) & 0xffffffffL - work = (leftt ^ right) & 0xaaaaaaaaL - leftt ^= work - right ^= work - leftt = ((leftt << 31) | (leftt >> 1)) & 0xffffffffL - work = ((leftt >> 8) ^ right) & 0x00ff00ffL - right ^= work - leftt ^= (work << 8) & 0xffffffffL - work = ((leftt >> 2) ^ right) & 0x33333333L - right ^= work - leftt ^= (work << 2) & 0xffffffffL - work = ((right >> 16) ^ leftt) & 0x0000ffffL - leftt ^= work - right ^= (work << 16) & 0xffffffffL - work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL - leftt ^= work - right ^= (work << 4) & 0xffffffffL - return right, leftt - -# Tables, permutations, S-boxes, etc. - -bytebit = [0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01] - -bigbyte = [ - 0x800000, 0x400000, 0x200000, 0x100000, - 0x080000, 0x040000, 0x020000, 0x010000, - 0x008000, 0x004000, 0x002000, 0x001000, - 0x000800, 0x000400, 0x000200, 0x000100, - 0x000080, 0x000040, 0x000020, 0x000010, - 0x000008, 0x000004, 0x000002, 0x000001 -] - -pc1 = [ - 56, 48, 40, 32, 24, 16, 8, - 0, 57, 49, 41, 33, 25, 17, - 9, 1, 58, 50, 42, 34, 26, - 18, 10, 2, 59, 51, 43, 35, - 62, 54, 46, 38, 30, 22, 14, - 6, 61, 53, 45, 37, 29, 21, - 13, 5, 60, 52, 44, 36, 28, - 20, 12, 4, 27, 19, 11, 3 -] - -totrot = [ - 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 -] - -pc2 = [ - 13, 16, 10, 23, 0, 4, - 2, 27, 14, 5, 20, 9, - 22, 18, 11, 3 , 25, 7, - 15, 6, 26, 19, 12, 1, - 40, 51, 30, 36, 46, 54, - 29, 39, 50, 44, 32, 47, - 43, 48, 38, 55, 33, 52, - 45, 41, 49, 35, 28, 31, -] - -# Microsoft's modified S-boxes for LIT file encryption -SP1 = [ -0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L, -0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L, -0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L, -0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L, -0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L, -0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L, -0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L, -0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L, -0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L, -0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L, -0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L, -0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L, -0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L, -0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L, -0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L, -0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L -] -SP2 = [ -0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L, -0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L, -0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L, -0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L, -0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L, -0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L, -0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L, -0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L, -0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L, -0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L, -0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L, -0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L, -0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L, -0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L, -0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L, -0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L -] -SP3 = [ -0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L, -0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L, -0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L, -0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L, -0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L, -0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L, -0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L, -0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L, -0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L, -0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L, -0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L, -0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L, -0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L, -0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L, -0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L, -0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L -] -SP4 = [ -0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L, -0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L, -0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L, -0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L, -0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L, -0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L, -0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L, -0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L, -0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L, -0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L, -0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L, -0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L, -0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L, -0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L, -0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L, -0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L -] -SP5 = [ -0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L, -0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L, -0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L, -0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L, -0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L, -0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L, -0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L, -0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L, -0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L, -0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L, -0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L, -0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L, -0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L, -0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L, -0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L, -0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L -] -SP6 = [ -0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L, -0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L, -0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L, -0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L, -0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L, -0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L, -0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L, -0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L, -0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L, -0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L, -0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L, -0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L, -0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L, -0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L, -0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L, -0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L, -] -SP7 = [ -0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L, -0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L, -0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L, -0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L, -0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L, -0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L, -0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L, -0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L, -0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L, -0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L, -0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L, -0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L, -0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L, -0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L, -0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L, -0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L, -] -SP8 = [ -0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L, -0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L, -0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L, -0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L, -0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L, -0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L, -0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L, -0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L, -0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L, -0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L, -0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L, -0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L, -0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L, -0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L, -0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L, -0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L, -] - -def new(key): - return DesCipher(key) - -block_size = 8 -key_size = 8 - -try: - import psyco - psyco.bind(DesCipher.deskey) - psyco.bind(DesCipher.cookey) - psyco.bind(DesCipher.des) -except ImportError: - pass - -#test only: -if __name__ == '__main__': - des = DesCipher("\x01\x23\x45\x67\x89\xab\xcd\xef") - print ''.join( - "%02x" % ord(x) for x in des.encrypt("Now is t")) - From 7eec1f5ba7f05481b15bb63f4558a88419718576 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 28 Jul 2008 08:35:56 -0700 Subject: [PATCH 26/34] IGN:Add 64bit dependencies to linux binary build --- installer/linux/freeze.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/installer/linux/freeze.py b/installer/linux/freeze.py index 7e33ea8be2..4627ad90ad 100644 --- a/installer/linux/freeze.py +++ b/installer/linux/freeze.py @@ -17,6 +17,8 @@ QTDIR = '/usr/lib/qt4' QTDLLS = ('QtCore', 'QtGui', 'QtNetwork', 'QtSvg', 'QtXml') EXTRAS = ('/usr/lib/python2.5/site-packages/PIL', os.path.expanduser('~/ipython/IPython')) SQLITE = '/usr/lib/libsqlite3.so.0' +DBUS = '/usr/lib/libdbus-1.so.3' +LIBMNG = '/usr/lib/libmng.so.1' CALIBRESRC = os.path.join(CALIBREPREFIX, 'src') @@ -115,7 +117,8 @@ binaries += [('clit', CLIT, 'BINARY'), ('pdftohtml', PDFTOHTML, 'BINARY'), ('libunrar.so', LIBUNRAR, 'BINARY')] print 'Adding external libraries...' -binaries += [(os.path.basename(SQLITE), SQLITE, 'BINARY')] +binaries += [ (os.path.basename(x), x, 'BINARY') for x in (SQLITE, DBUS, LIBMNG)] + qt = [] for dll in QTDLLS: From d42c3031ae69eaff839a44279508621d475d0c66 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 28 Jul 2008 15:03:28 -0700 Subject: [PATCH 27/34] Add support for writing metadata to epub-meta --- src/calibre/ebooks/metadata/epub.py | 55 +- src/calibre/ebooks/metadata/meta.py | 3 + src/calibre/linux.py | 3 +- src/calibre/utils/zipfile.py | 914 +++++++++++++++++++++------- 4 files changed, 747 insertions(+), 228 deletions(-) diff --git a/src/calibre/ebooks/metadata/epub.py b/src/calibre/ebooks/metadata/epub.py index 6f8f211552..44eaedaf26 100644 --- a/src/calibre/ebooks/metadata/epub.py +++ b/src/calibre/ebooks/metadata/epub.py @@ -7,13 +7,13 @@ __copyright__ = '2008, Kovid Goyal ' import sys, os -from zipfile import ZipFile, BadZipfile +from calibre.utils.zipfile import ZipFile, BadZipfile from cStringIO import StringIO from contextlib import closing from calibre.ebooks.BeautifulSoup import BeautifulStoneSoup -from calibre.ebooks.metadata.opf import OPF, OPFReader - +from calibre.ebooks.metadata.opf import OPF, OPFReader, OPFCreator +from calibre.ebooks.metadata import get_parser, MetaInformation class EPubException(Exception): pass @@ -71,9 +71,9 @@ class OCFReader(OCF): raise EPubException("missing OPF package file") class OCFZipReader(OCFReader): - def __init__(self, stream): + def __init__(self, stream, mode='r'): try: - self.archive = ZipFile(stream, 'r') + self.archive = ZipFile(stream, mode) except BadZipfile: raise EPubException("not a ZIP .epub OCF container") self.root = getattr(stream, 'name', os.getcwd()) @@ -81,6 +81,19 @@ class OCFZipReader(OCFReader): def open(self, name, mode='r'): return StringIO(self.archive.read(name)) + +class OCFZipWriter(OCFZipReader): + + def __init__(self, stream): + OCFZipReader.__init__(self, stream, mode='a') + + def set_metadata(self, mi): + name = self.container[OPF.MIMETYPE] + stream = StringIO() + opf = OPFCreator(self.root, mi) + opf.render(stream) + self.archive.delete(name) + self.archive.writestr(name, stream.getvalue()) class OCFDirReader(OCFReader): def __init__(self, path): @@ -95,13 +108,35 @@ def get_metadata(stream): """ Return metadata as a L{MetaInfo} object """ return OCFZipReader(stream).opf +def set_metadata(stream, mi): + OCFZipWriter(stream).set_metadata(mi) + +def option_parser(): + parser = get_parser('epub') + parser.remove_option('--category') + parser.add_option('--tags', default=None, help=_('A comma separated list of tags to set')) + return parser + def main(args=sys.argv): - if len(args) != 2 or '--help' in args or '-h' in args: - print >>sys.stderr, _('Usage:'), args[0], _('mybook.epub') + parser = option_parser() + opts, args = parser.parse_args(args) + if len(args) != 2: + parser.print_help() return 1 - - path = os.path.abspath(os.path.expanduser(args[1])) - print unicode(get_metadata(open(path, 'rb'))) + stream = open(args[1], 'r+b') + mi = MetaInformation(OCFZipReader(stream).opf) + if opts.title: + mi.title = opts.title + if opts.authors: + mi.authors = opts.authors.split(',') + if opts.tags: + mi.tags = opts.tags.split(',') + if opts.comment: + mi.comments = opts.comment + + set_metadata(stream, mi) + + print unicode(mi) return 0 if __name__ == '__main__': diff --git a/src/calibre/ebooks/metadata/meta.py b/src/calibre/ebooks/metadata/meta.py index f05a31654e..15db121cb0 100644 --- a/src/calibre/ebooks/metadata/meta.py +++ b/src/calibre/ebooks/metadata/meta.py @@ -14,6 +14,7 @@ from calibre.ebooks.mobi.reader import get_metadata as mobi_metadata from calibre.ebooks.metadata.opf import OPFReader from calibre.ebooks.metadata.rtf import set_metadata as set_rtf_metadata from calibre.ebooks.lrf.meta import set_metadata as set_lrf_metadata +from calibre.ebooks.metadata.epub import set_metadata as set_epub_metadata from calibre.ebooks.metadata import MetaInformation @@ -88,6 +89,8 @@ def set_metadata(stream, mi, stream_type='lrf'): if stream_type: stream_type = stream_type.lower() if stream_type == 'lrf': set_lrf_metadata(stream, mi) + elif stream_type == 'epub': + set_epub_metadata(stream, mi) elif stream_type == 'rtf': set_rtf_metadata(stream, mi) diff --git a/src/calibre/linux.py b/src/calibre/linux.py index eaaeabcb4c..1cb0a1ff81 100644 --- a/src/calibre/linux.py +++ b/src/calibre/linux.py @@ -165,6 +165,7 @@ def setup_completion(fatal_errors): from calibre.web.feeds.main import option_parser as feeds2disk from calibre.web.feeds.recipes import titles as feed_titles from calibre.ebooks.lrf.feeds.convert_from import option_parser as feeds2lrf + from calibre.ebooks.metadata.epub import option_parser as epub_meta f = open_file('/etc/bash_completion.d/libprs500') f.close() @@ -192,7 +193,7 @@ def setup_completion(fatal_errors): f.write(opts_and_exts('pdf-meta', metaop, ['pdf'])) f.write(opts_and_exts('lit-meta', metaop, ['lit'])) f.write(opts_and_exts('opf-meta', metaop, ['opf'])) - f.write(opts_and_exts('epub-meta', metaop, ['epub'])) + f.write(opts_and_exts('epub-meta', epub_meta, ['epub'])) f.write(opts_and_exts('lrfviewer', lrfviewerop, ['lrf'])) f.write(opts_and_exts('pdfrelow', pdfhtmlop, ['pdf'])) f.write(opts_and_exts('mobi2oeb', mobioeb, ['mobi', 'prc'])) diff --git a/src/calibre/utils/zipfile.py b/src/calibre/utils/zipfile.py index 56fca9349b..02f7eac5c4 100644 --- a/src/calibre/utils/zipfile.py +++ b/src/calibre/utils/zipfile.py @@ -1,14 +1,16 @@ """ -Read and write ZIP files. Modified by Kovid Goyal to allow replacing of files -in the ZIP archive. +Read and write ZIP files. Modified by Kovid Goyal to support replacing files in +a zip archive. """ -import struct, os, time, sys +import struct, os, time, sys, shutil import binascii, cStringIO try: import zlib # We may need its compression method + crc32 = zlib.crc32 except ImportError: zlib = None + crc32 = binascii.crc32 __all__ = ["BadZipfile", "error", "ZIP_STORED", "ZIP_DEFLATED", "is_zipfile", "ZipInfo", "ZipFile", "PyZipFile", "LargeZipFile" ] @@ -26,31 +28,51 @@ class LargeZipFile(Exception): error = BadZipfile # The exception raised by this module ZIP64_LIMIT= (1 << 31) - 1 +ZIP_FILECOUNT_LIMIT = 1 << 16 +ZIP_MAX_COMMENT = (1 << 16) - 1 # constants for Zip file compression methods ZIP_STORED = 0 ZIP_DEFLATED = 8 # Other ZIP compression methods not supported -# Here are some struct module formats for reading headers -structEndArchive = "<4s4H2LH" # 9 items, end of archive, 22 bytes -stringEndArchive = "PK\005\006" # magic number for end of archive record -structCentralDir = "<4s4B4HlLL5HLL"# 19 items, central directory, 46 bytes -stringCentralDir = "PK\001\002" # magic number for central directory -structFileHeader = "<4s2B4HlLL2H" # 12 items, file header record, 30 bytes -stringFileHeader = "PK\003\004" # magic number for file header -structEndArchive64Locator = "<4slql" # 4 items, locate Zip64 header, 20 bytes -stringEndArchive64Locator = "PK\x06\x07" # magic token for locator header -structEndArchive64 = "<4sqhhllqqqq" # 10 items, end of archive (Zip64), 56 bytes -stringEndArchive64 = "PK\x06\x06" # magic token for Zip64 header +# Below are some formats and associated data for reading/writing headers using +# the struct module. The names and structures of headers/records are those used +# in the PKWARE description of the ZIP file format: +# http://www.pkware.com/documents/casestudies/APPNOTE.TXT +# (URL valid as of January 2008) +# The "end of central directory" structure, magic number, size, and indices +# (section V.I in the format document) +structEndArchive = "<4s4H2LH" +stringEndArchive = "PK\005\006" +sizeEndCentDir = struct.calcsize(structEndArchive) + +_ECD_SIGNATURE = 0 +_ECD_DISK_NUMBER = 1 +_ECD_DISK_START = 2 +_ECD_ENTRIES_THIS_DISK = 3 +_ECD_ENTRIES_TOTAL = 4 +_ECD_SIZE = 5 +_ECD_OFFSET = 6 +_ECD_COMMENT_SIZE = 7 +# These last two indices are not part of the structure as defined in the +# spec, but they are used internally by this module as a convenience +_ECD_COMMENT = 8 +_ECD_LOCATION = 9 + +# The "central directory" structure, magic number, size, and indices +# of entries in the structure (section V.F in the format document) +structCentralDir = "<4s4B4HL2L5H2L" +stringCentralDir = "PK\001\002" +sizeCentralDir = struct.calcsize(structCentralDir) # indexes of entries in the central directory structure _CD_SIGNATURE = 0 _CD_CREATE_VERSION = 1 _CD_CREATE_SYSTEM = 2 _CD_EXTRACT_VERSION = 3 -_CD_EXTRACT_SYSTEM = 4 # is this meaningful? +_CD_EXTRACT_SYSTEM = 4 _CD_FLAG_BITS = 5 _CD_COMPRESS_TYPE = 6 _CD_TIME = 7 @@ -66,10 +88,15 @@ _CD_INTERNAL_FILE_ATTRIBUTES = 16 _CD_EXTERNAL_FILE_ATTRIBUTES = 17 _CD_LOCAL_HEADER_OFFSET = 18 -# indexes of entries in the local file header structure +# The "local file header" structure, magic number, size, and indices +# (section V.A in the format document) +structFileHeader = "<4s2B4HL2L2H" +stringFileHeader = "PK\003\004" +sizeFileHeader = struct.calcsize(structFileHeader) + _FH_SIGNATURE = 0 _FH_EXTRACT_VERSION = 1 -_FH_EXTRACT_SYSTEM = 2 # is this meaningful? +_FH_EXTRACT_SYSTEM = 2 _FH_GENERAL_PURPOSE_FLAG_BITS = 3 _FH_COMPRESSION_METHOD = 4 _FH_LAST_MOD_TIME = 5 @@ -80,6 +107,28 @@ _FH_UNCOMPRESSED_SIZE = 9 _FH_FILENAME_LENGTH = 10 _FH_EXTRA_FIELD_LENGTH = 11 +# The "Zip64 end of central directory locator" structure, magic number, and size +structEndArchive64Locator = "<4sLQL" +stringEndArchive64Locator = "PK\x06\x07" +sizeEndCentDir64Locator = struct.calcsize(structEndArchive64Locator) + +# The "Zip64 end of central directory" record, magic number, size, and indices +# (section V.G in the format document) +structEndArchive64 = "<4sQ2H2L4Q" +stringEndArchive64 = "PK\x06\x06" +sizeEndCentDir64 = struct.calcsize(structEndArchive64) + +_CD64_SIGNATURE = 0 +_CD64_DIRECTORY_RECSIZE = 1 +_CD64_CREATE_VERSION = 2 +_CD64_EXTRACT_VERSION = 3 +_CD64_DISK_NUMBER = 4 +_CD64_DISK_NUMBER_START = 5 +_CD64_NUMBER_ENTRIES_THIS_DISK = 6 +_CD64_NUMBER_ENTRIES_TOTAL = 7 +_CD64_DIRECTORY_SIZE = 8 +_CD64_OFFSET_START_CENTDIR = 9 + def is_zipfile(filename): """Quickly see if file is a ZIP file by checking the magic number.""" try: @@ -96,9 +145,8 @@ def _EndRecData64(fpin, offset, endrec): """ Read the ZIP64 end-of-archive records and use that to update endrec """ - locatorSize = struct.calcsize(structEndArchive64Locator) - fpin.seek(offset - locatorSize, 2) - data = fpin.read(locatorSize) + fpin.seek(offset - sizeEndCentDir64Locator, 2) + data = fpin.read(sizeEndCentDir64Locator) sig, diskno, reloff, disks = struct.unpack(structEndArchive64Locator, data) if sig != stringEndArchive64Locator: return endrec @@ -107,9 +155,8 @@ def _EndRecData64(fpin, offset, endrec): raise BadZipfile("zipfiles that span multiple disks are not supported") # Assume no 'zip64 extensible data' - endArchiveSize = struct.calcsize(structEndArchive64) - fpin.seek(offset - locatorSize - endArchiveSize, 2) - data = fpin.read(endArchiveSize) + fpin.seek(offset - sizeEndCentDir64Locator - sizeEndCentDir64, 2) + data = fpin.read(sizeEndCentDir64) sig, sz, create_version, read_version, disk_num, disk_dir, \ dircount, dircount2, dirsize, diroffset = \ struct.unpack(structEndArchive64, data) @@ -117,12 +164,12 @@ def _EndRecData64(fpin, offset, endrec): return endrec # Update the original endrec using data from the ZIP64 record - endrec[1] = disk_num - endrec[2] = disk_dir - endrec[3] = dircount - endrec[4] = dircount2 - endrec[5] = dirsize - endrec[6] = diroffset + endrec[_ECD_DISK_NUMBER] = disk_num + endrec[_ECD_DISK_START] = disk_dir + endrec[_ECD_ENTRIES_THIS_DISK] = dircount + endrec[_ECD_ENTRIES_TOTAL] = dircount2 + endrec[_ECD_SIZE] = dirsize + endrec[_ECD_OFFSET] = diroffset return endrec @@ -131,38 +178,59 @@ def _EndRecData(fpin): The data is a list of the nine items in the ZIP "End of central dir" record followed by a tenth item, the file seek offset of this record.""" - fpin.seek(-22, 2) # Assume no archive comment. - filesize = fpin.tell() + 22 # Get file size + + # Determine file size + fpin.seek(0, 2) + filesize = fpin.tell() + + # Check to see if this is ZIP file with no archive comment (the + # "end of central directory" structure should be the last item in the + # file if this is the case). + fpin.seek(-sizeEndCentDir, 2) data = fpin.read() if data[0:4] == stringEndArchive and data[-2:] == "\000\000": + # the signature is correct and there's no comment, unpack structure endrec = struct.unpack(structEndArchive, data) - endrec = list(endrec) - endrec.append("") # Append the archive comment - endrec.append(filesize - 22) # Append the record start offset - if endrec[-4] == -1 or endrec[-4] == 0xffffffff: - return _EndRecData64(fpin, -22, endrec) + endrec=list(endrec) + + # Append a blank comment and record start offset + endrec.append("") + endrec.append(filesize - sizeEndCentDir) + if endrec[_ECD_OFFSET] == 0xffffffff: + # the value for the "offset of the start of the central directory" + # indicates that there is a "Zip64 end of central directory" + # structure present, so go look for it + return _EndRecData64(fpin, -sizeEndCentDir, endrec) + return endrec - # Search the last END_BLOCK bytes of the file for the record signature. - # The comment is appended to the ZIP file and has a 16 bit length. - # So the comment may be up to 64K long. We limit the search for the - # signature to a few Kbytes at the end of the file for efficiency. - # also, the signature must not appear in the comment. - END_BLOCK = min(filesize, 1024 * 4) - fpin.seek(filesize - END_BLOCK, 0) + + # Either this is not a ZIP file, or it is a ZIP file with an archive + # comment. Search the end of the file for the "end of central directory" + # record signature. The comment is the last item in the ZIP file and may be + # up to 64K long. It is assumed that the "end of central directory" magic + # number does not appear in the comment. + maxCommentStart = max(filesize - (1 << 16) - sizeEndCentDir, 0) + fpin.seek(maxCommentStart, 0) data = fpin.read() start = data.rfind(stringEndArchive) - if start >= 0: # Correct signature string was found - endrec = struct.unpack(structEndArchive, data[start:start+22]) - endrec = list(endrec) - comment = data[start+22:] - if endrec[7] == len(comment): # Comment length checks out + if start >= 0: + # found the magic number; attempt to unpack and interpret + recData = data[start:start+sizeEndCentDir] + endrec = list(struct.unpack(structEndArchive, recData)) + comment = data[start+sizeEndCentDir:] + # check that comment length is correct + if endrec[_ECD_COMMENT_SIZE] == len(comment): # Append the archive comment and start offset endrec.append(comment) - endrec.append(filesize - END_BLOCK + start) - if endrec[-4] == -1 or endrec[-4] == 0xffffffff: - return _EndRecData64(fpin, - END_BLOCK + start, endrec) + endrec.append(maxCommentStart + start) + if endrec[_ECD_OFFSET] == 0xffffffff: + # There is apparently a "Zip64 end of central directory" + # structure present, so go look for it + return _EndRecData64(fpin, start - filesize, endrec) return endrec - return # Error, return None + + # Unable to find a valid end of central directory structure + return class ZipInfo (object): @@ -187,6 +255,7 @@ class ZipInfo (object): 'CRC', 'compress_size', 'file_size', + '_raw_time', 'file_offset', ) @@ -247,34 +316,50 @@ class ZipInfo (object): if file_size > ZIP64_LIMIT or compress_size > ZIP64_LIMIT: # File is larger than what fits into a 4 byte integer, # fall back to the ZIP64 extension - fmt = '= 24: - counts = unpack('> 1) & 0x7FFFFFFF) ^ poly + else: + crc = ((crc >> 1) & 0x7FFFFFFF) + table[i] = crc + return table + crctable = _GenerateCRCTable() + + def _crc32(self, ch, crc): + """Compute the CRC32 primitive on one byte.""" + return ((crc >> 8) & 0xffffff) ^ self.crctable[(crc ^ ord(ch)) & 0xff] + + def __init__(self, pwd): + self.key0 = 305419896 + self.key1 = 591751049 + self.key2 = 878082192 + for p in pwd: + self._UpdateKeys(p) + + def _UpdateKeys(self, c): + self.key0 = self._crc32(c, self.key0) + self.key1 = (self.key1 + (self.key0 & 255)) & 4294967295 + self.key1 = (self.key1 * 134775813 + 1) & 4294967295 + self.key2 = self._crc32(chr((self.key1 >> 24) & 255), self.key2) + + def __call__(self, c): + """Decrypt a single character.""" + c = ord(c) + k = self.key2 | 2 + c = c ^ (((k * (k^1)) >> 8) & 255) + c = chr(c) + self._UpdateKeys(c) + return c + +class ZipExtFile: + """File-like object for reading an archive member. + Is returned by ZipFile.open(). + """ + + def __init__(self, fileobj, zipinfo, decrypt=None): + self.fileobj = fileobj + self.decrypter = decrypt + self.bytes_read = 0L + self.rawbuffer = '' + self.readbuffer = '' + self.linebuffer = '' + self.eof = False + self.univ_newlines = False + self.nlSeps = ("\n", ) + self.lastdiscard = '' + + self.compress_type = zipinfo.compress_type + self.compress_size = zipinfo.compress_size + + self.closed = False + self.mode = "r" + self.name = zipinfo.filename + + # read from compressed files in 64k blocks + self.compreadsize = 64*1024 + if self.compress_type == ZIP_DEFLATED: + self.dc = zlib.decompressobj(-15) + + def set_univ_newlines(self, univ_newlines): + self.univ_newlines = univ_newlines + + # pick line separator char(s) based on universal newlines flag + self.nlSeps = ("\n", ) + if self.univ_newlines: + self.nlSeps = ("\r\n", "\r", "\n") + + def __iter__(self): + return self + + def next(self): + nextline = self.readline() + if not nextline: + raise StopIteration() + + return nextline + + def close(self): + self.closed = True + + def _checkfornewline(self): + nl, nllen = -1, -1 + if self.linebuffer: + # ugly check for cases where half of an \r\n pair was + # read on the last pass, and the \r was discarded. In this + # case we just throw away the \n at the start of the buffer. + if (self.lastdiscard, self.linebuffer[0]) == ('\r','\n'): + self.linebuffer = self.linebuffer[1:] + + for sep in self.nlSeps: + nl = self.linebuffer.find(sep) + if nl >= 0: + nllen = len(sep) + return nl, nllen + + return nl, nllen + + def readline(self, size = -1): + """Read a line with approx. size. If size is negative, + read a whole line. + """ + if size < 0: + size = sys.maxint + elif size == 0: + return '' + + # check for a newline already in buffer + nl, nllen = self._checkfornewline() + + if nl >= 0: + # the next line was already in the buffer + nl = min(nl, size) + else: + # no line break in buffer - try to read more + size -= len(self.linebuffer) + while nl < 0 and size > 0: + buf = self.read(min(size, 100)) + if not buf: + break + self.linebuffer += buf + size -= len(buf) + + # check for a newline in buffer + nl, nllen = self._checkfornewline() + + # we either ran out of bytes in the file, or + # met the specified size limit without finding a newline, + # so return current buffer + if nl < 0: + s = self.linebuffer + self.linebuffer = '' + return s + + buf = self.linebuffer[:nl] + self.lastdiscard = self.linebuffer[nl:nl + nllen] + self.linebuffer = self.linebuffer[nl + nllen:] + + # line is always returned with \n as newline char (except possibly + # for a final incomplete line in the file, which is handled above). + return buf + "\n" + + def readlines(self, sizehint = -1): + """Return a list with all (following) lines. The sizehint parameter + is ignored in this implementation. + """ + result = [] + while True: + line = self.readline() + if not line: break + result.append(line) + return result + + def read(self, size = None): + # act like file() obj and return empty string if size is 0 + if size == 0: + return '' + + # determine read size + bytesToRead = self.compress_size - self.bytes_read + + # adjust read size for encrypted files since the first 12 bytes + # are for the encryption/password information + if self.decrypter is not None: + bytesToRead -= 12 + + if size is not None and size >= 0: + if self.compress_type == ZIP_STORED: + lr = len(self.readbuffer) + bytesToRead = min(bytesToRead, size - lr) + elif self.compress_type == ZIP_DEFLATED: + if len(self.readbuffer) > size: + # the user has requested fewer bytes than we've already + # pulled through the decompressor; don't read any more + bytesToRead = 0 + else: + # user will use up the buffer, so read some more + lr = len(self.rawbuffer) + bytesToRead = min(bytesToRead, self.compreadsize - lr) + + # avoid reading past end of file contents + if bytesToRead + self.bytes_read > self.compress_size: + bytesToRead = self.compress_size - self.bytes_read + + # try to read from file (if necessary) + if bytesToRead > 0: + bytes = self.fileobj.read(bytesToRead) + self.bytes_read += len(bytes) + self.rawbuffer += bytes + + # handle contents of raw buffer + if self.rawbuffer: + newdata = self.rawbuffer + self.rawbuffer = '' + + # decrypt new data if we were given an object to handle that + if newdata and self.decrypter is not None: + newdata = ''.join(map(self.decrypter, newdata)) + + # decompress newly read data if necessary + if newdata and self.compress_type == ZIP_DEFLATED: + newdata = self.dc.decompress(newdata) + self.rawbuffer = self.dc.unconsumed_tail + if self.eof and len(self.rawbuffer) == 0: + # we're out of raw bytes (both from the file and + # the local buffer); flush just to make sure the + # decompressor is done + newdata += self.dc.flush() + # prevent decompressor from being used again + self.dc = None + + self.readbuffer += newdata + + + # return what the user asked for + if size is None or len(self.readbuffer) <= size: + bytes = self.readbuffer + self.readbuffer = '' + else: + bytes = self.readbuffer[:size] + self.readbuffer = self.readbuffer[size:] + + return bytes + + +class ZipFile: + """ Class with methods to open, read, write, close, list and update zip files. + + z = ZipFile(file, mode="r", compression=ZIP_STORED, allowZip64=False) file: Either the path to the file, or a file-like object. If it is a path, the file will be opened and closed by ZipFile. @@ -318,8 +655,9 @@ class ZipFile: def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=False): """Open the ZIP file with mode read "r", write "w" or append "a".""" - self._allowZip64 = allowZip64 - self._didModify = False + if mode not in ("r", "w", "a"): + raise RuntimeError('ZipFile() requires mode "r", "w", or "a"') + if compression == ZIP_STORED: pass elif compression == ZIP_DEFLATED: @@ -328,18 +666,30 @@ class ZipFile: "Compression requires the (missing) zlib module" else: raise RuntimeError, "That compression method is not supported" + + self._allowZip64 = allowZip64 + self._didModify = False self.debug = 0 # Level of printing: 0 through 3 self.NameToInfo = {} # Find file info given name self.filelist = [] # List of ZipInfo instances for archive self.compression = compression # Method of compression self.mode = key = mode.replace('b', '')[0] + self.pwd = None + self.comment = '' # Check if we were passed a file-like object if isinstance(file, basestring): self._filePassed = 0 self.filename = file modeDict = {'r' : 'rb', 'w': 'wb', 'a' : 'r+b'} - self.fp = open(file, modeDict[mode]) + try: + self.fp = open(file, modeDict[mode]) + except IOError: + if mode == 'a': + mode = key = 'w' + self.fp = open(file, modeDict[mode]) + else: + raise else: self._filePassed = 1 self.fp = file @@ -382,18 +732,20 @@ class ZipFile: raise BadZipfile, "File is not a zip file" if self.debug > 1: print endrec - size_cd = endrec[5] # bytes in central directory - offset_cd = endrec[6] # offset of central directory - self.comment = endrec[8] # archive comment - # endrec[9] is the offset of the "End of Central Dir" record - if endrec[9] > ZIP64_LIMIT: - x = endrec[9] - size_cd - 56 - 20 - else: - x = endrec[9] - size_cd + size_cd = endrec[_ECD_SIZE] # bytes in central directory + offset_cd = endrec[_ECD_OFFSET] # offset of central directory + self.comment = endrec[_ECD_COMMENT] # archive comment + # "concat" is zero, unless zip was concatenated to another file - concat = x - offset_cd + concat = endrec[_ECD_LOCATION] - size_cd - offset_cd + if endrec[_ECD_LOCATION] > ZIP64_LIMIT: + # If the offset of the "End of Central Dir" record requires Zip64 + # extension structures, account for them + concat -= (sizeEndCentDir64 + sizeEndCentDir64Locator) + if self.debug > 2: - print "given, inferred, offset", offset_cd, x, concat + inferred = concat + offset_cd + print "given, inferred, offset", offset_cd, inferred, concat # self.start_dir: Position of start of central directory self.start_dir = offset_cd + concat fp.seek(self.start_dir, 0) @@ -401,8 +753,7 @@ class ZipFile: fp = cStringIO.StringIO(data) total = 0 while total < size_cd: - centdir = fp.read(46) - total = total + 46 + centdir = fp.read(sizeCentralDir) if centdir[0:4] != stringCentralDir: raise BadZipfile, "Bad magic number for central directory" centdir = struct.unpack(structCentralDir, centdir) @@ -413,100 +764,103 @@ class ZipFile: x = ZipInfo(filename) x.extra = fp.read(centdir[_CD_EXTRA_FIELD_LENGTH]) x.comment = fp.read(centdir[_CD_COMMENT_LENGTH]) - total = (total + centdir[_CD_FILENAME_LENGTH] - + centdir[_CD_EXTRA_FIELD_LENGTH] - + centdir[_CD_COMMENT_LENGTH]) x.header_offset = centdir[_CD_LOCAL_HEADER_OFFSET] (x.create_version, x.create_system, x.extract_version, x.reserved, x.flag_bits, x.compress_type, t, d, x.CRC, x.compress_size, x.file_size) = centdir[1:12] x.volume, x.internal_attr, x.external_attr = centdir[15:18] # Convert date/time code to (year, month, day, hour, min, sec) + x._raw_time = t x.date_time = ( (d>>9)+1980, (d>>5)&0xF, d&0x1F, t>>11, (t>>5)&0x3F, (t&0x1F) * 2 ) x._decodeExtra() x.header_offset = x.header_offset + concat + x.filename = x._decodeFilename() self.filelist.append(x) self.NameToInfo[x.filename] = x + + # update total bytes read from central directory + total = (total + sizeCentralDir + centdir[_CD_FILENAME_LENGTH] + + centdir[_CD_EXTRA_FIELD_LENGTH] + + centdir[_CD_COMMENT_LENGTH]) + if self.debug > 2: print "total", total - - + def _calculate_file_offsets(self): - for zip_info in self.filelist: - self.fp.seek(zip_info.header_offset, 0) - fheader = self.fp.read(30) - if fheader[0:4] != stringFileHeader: - raise BadZipfile, "Bad magic number for file header" - fheader = struct.unpack(structFileHeader, fheader) - # file_offset is computed here, since the extra field for - # the central directory and for the local file header - # refer to different fields, and they can have different - # lengths - file_offset = (zip_info.header_offset + 30 - + fheader[_FH_FILENAME_LENGTH] - + fheader[_FH_EXTRA_FIELD_LENGTH]) - fname = self.fp.read(fheader[_FH_FILENAME_LENGTH]) - if fname != zip_info.orig_filename: - raise RuntimeError, \ - 'File name in directory "%s" and header "%s" differ.' % ( - zip_info.orig_filename, fname) - + for zip_info in self.filelist: + self.fp.seek(zip_info.header_offset, 0) + fheader = self.fp.read(30) + if fheader[0:4] != stringFileHeader: + raise BadZipfile, "Bad magic number for file header" + fheader = struct.unpack(structFileHeader, fheader) + # file_offset is computed here, since the extra field for + # the central directory and for the local file header + # refer to different fields, and they can have different + # lengths + file_offset = (zip_info.header_offset + 30 + + fheader[_FH_FILENAME_LENGTH] + + fheader[_FH_EXTRA_FIELD_LENGTH]) + fname = self.fp.read(fheader[_FH_FILENAME_LENGTH]) + if fname != zip_info.orig_filename: + raise RuntimeError( + 'File name in directory "%s" and header "%s" differ.' % ( + zip_info.orig_filename, fname)) + zip_info.file_offset = file_offset + + def replace(self, filename, arcname=None, compress_type=None): + """Delete arcname, and put the bytes from filename into the + archive under the name arcname.""" + deleteName = arcname + if deleteName is None: + deleteName = filename + self.delete(deleteName) + self.write(filename, arcname, compress_type) + + def replacestr(self, zinfo, bytes): + """Delete zinfo.filename, and write a new file into the archive. The + contents is the string 'bytes'.""" + self.delete(zinfo.filename) + self.writestr(zinfo, bytes) - - def replace(self, filename, arcname=None, compress_type=None): - """Delete arcname, and put the bytes from filename into the - archive under the name arcname.""" - deleteName = arcname - if deleteName is None: - deleteName = filename - self.delete(deleteName) - self.write(filename, arcname, compress_type) - - def replacestr(self, zinfo, bytes): - """Delete zinfo.filename, and write a new file into the archive. The - contents is the string 'bytes'.""" - self.delete(zinfo.filename) - self.writestr(zinfo, bytes) - - def delete(self, name): - """Delete the file from the archive. If it appears multiple - times only the first instance will be deleted.""" - for i in range (0, len(self.filelist)): - if self.filelist[i].filename == name: - if self.debug: - print "Removing", name - deleted_offset = self.filelist[i].header_offset + def delete(self, name): + """Delete the file from the archive. If it appears multiple + times only the first instance will be deleted.""" + for i in range (0, len(self.filelist)): + if self.filelist[i].filename == name: + if self.debug: + print "Removing", name + deleted_offset = self.filelist[i].header_offset deleted_size = (self.filelist[i].file_offset - self.filelist[i].header_offset) + self.filelist[i].compress_size - zinfo_size = struct.calcsize(structCentralDir) + len(self.filelist[i].filename) + len(self.filelist[i].extra) - # Remove the file's data from the archive. - current_offset = self.fp.tell() - self.fp.seek(0, 2) - archive_size = self.fp.tell() - self.fp.seek(deleted_offset + deleted_size) - buf = self.fp.read() - self.fp.seek(deleted_offset) - self.fp.write(buf) - self.fp.truncate(archive_size - deleted_size - zinfo_size) - if current_offset > deleted_offset + deleted_size: - current_offset -= deleted_size - elif current_offset > deleted_offset: - current_offset = deleted_offset - self.fp.seek(current_offset, 0) - # Remove file from central directory. - del self.filelist[i] - # Adjust the remaining offsets in the central directory. - for j in range (i, len(self.filelist)): - if self.filelist[j].header_offset > deleted_offset: - self.filelist[j].header_offset -= deleted_size - if self.filelist[j].file_offset > deleted_offset: - self.filelist[j].file_offset -= deleted_size - return - if self.debug: - print name, "not in archive" - + zinfo_size = struct.calcsize(structCentralDir) + len(self.filelist[i].filename) + len(self.filelist[i].extra) + # Remove the file's data from the archive. + current_offset = self.fp.tell() + self.fp.seek(0, 2) + archive_size = self.fp.tell() + self.fp.seek(deleted_offset + deleted_size) + buf = self.fp.read() + self.fp.seek(deleted_offset) + self.fp.write(buf) + self.fp.truncate(archive_size - deleted_size - zinfo_size) + if current_offset > deleted_offset + deleted_size: + current_offset -= deleted_size + elif current_offset > deleted_offset: + current_offset = deleted_offset + self.fp.seek(current_offset, 0) + # Remove file from central directory. + del self.filelist[i] + # Adjust the remaining offsets in the central directory. + for j in range (i, len(self.filelist)): + if self.filelist[j].header_offset > deleted_offset: + self.filelist[j].header_offset -= deleted_size + if self.filelist[j].file_offset > deleted_offset: + self.filelist[j].file_offset -= deleted_size + return + if self.debug: + print name, "not in archive" + def namelist(self): """Return a list of file names in the archive.""" l = [] @@ -534,61 +888,156 @@ class ZipFile: except BadZipfile: return zinfo.filename - def getinfo(self, name): """Return the instance of ZipInfo given 'name'.""" - return self.NameToInfo[name] + info = self.NameToInfo.get(name) + if info is None: + raise KeyError( + 'There is no item named %r in the archive' % name) - def read(self, name): + return info + + def setpassword(self, pwd): + """Set default password for encrypted files.""" + self.pwd = pwd + + def read(self, name, pwd=None): """Return file bytes (as a string) for name.""" - if self.mode not in ("r", "a"): - raise RuntimeError, 'read() requires mode "r" or "a"' + return self.open(name, "r", pwd).read() + + def open(self, name, mode="r", pwd=None): + """Return file-like object for 'name'.""" + if mode not in ("r", "U", "rU"): + raise RuntimeError, 'open() requires mode "r", "U", or "rU"' if not self.fp: raise RuntimeError, \ "Attempt to read ZIP archive that was already closed" - zinfo = self.getinfo(name) - filepos = self.fp.tell() - self.fp.seek(zinfo.header_offset, 0) + # Only open a new file for instances where we were not + # given a file object in the constructor + if self._filePassed: + zef_file = self.fp + else: + zef_file = open(self.filename, 'rb') + + # Make sure we have an info object + if isinstance(name, ZipInfo): + # 'name' is already an info object + zinfo = name + else: + # Get info object for name + zinfo = self.getinfo(name) + + zef_file.seek(zinfo.header_offset, 0) # Skip the file header: - fheader = self.fp.read(30) + fheader = zef_file.read(sizeFileHeader) if fheader[0:4] != stringFileHeader: raise BadZipfile, "Bad magic number for file header" fheader = struct.unpack(structFileHeader, fheader) - fname = self.fp.read(fheader[_FH_FILENAME_LENGTH]) + fname = zef_file.read(fheader[_FH_FILENAME_LENGTH]) if fheader[_FH_EXTRA_FIELD_LENGTH]: - self.fp.read(fheader[_FH_EXTRA_FIELD_LENGTH]) + zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH]) if fname != zinfo.orig_filename: raise BadZipfile, \ 'File name in directory "%s" and header "%s" differ.' % ( zinfo.orig_filename, fname) - bytes = self.fp.read(zinfo.compress_size) - self.fp.seek(filepos, 0) - if zinfo.compress_type == ZIP_STORED: - pass - elif zinfo.compress_type == ZIP_DEFLATED: - if not zlib: - raise RuntimeError, \ - "De-compression requires the (missing) zlib module" - # zlib compress/decompress code by Jeremy Hylton of CNRI - dc = zlib.decompressobj(-15) - bytes = dc.decompress(bytes) - # need to feed in unused pad byte so that zlib won't choke - ex = dc.decompress('Z') + dc.flush() - if ex: - bytes = bytes + ex + # check for encrypted flag & handle password + is_encrypted = zinfo.flag_bits & 0x1 + zd = None + if is_encrypted: + if not pwd: + pwd = self.pwd + if not pwd: + raise RuntimeError, "File %s is encrypted, " \ + "password required for extraction" % name + + zd = _ZipDecrypter(pwd) + # The first 12 bytes in the cypher stream is an encryption header + # used to strengthen the algorithm. The first 11 bytes are + # completely random, while the 12th contains the MSB of the CRC, + # or the MSB of the file time depending on the header type + # and is used to check the correctness of the password. + bytes = zef_file.read(12) + h = map(zd, bytes[0:12]) + if zinfo.flag_bits & 0x8: + # compare against the file type from extended local headers + check_byte = (zinfo._raw_time >> 8) & 0xff + else: + # compare against the CRC otherwise + check_byte = (zinfo.CRC >> 24) & 0xff + if ord(h[11]) != check_byte: + raise RuntimeError("Bad password for file", name) + + # build and return a ZipExtFile + if zd is None: + zef = ZipExtFile(zef_file, zinfo) else: - raise BadZipfile, \ - "Unsupported compression method %d for file %s" % \ - (zinfo.compress_type, name) - crc = binascii.crc32(bytes) - if crc != zinfo.CRC: - raise BadZipfile, "Bad CRC-32 for file %s" % name - return bytes + zef = ZipExtFile(zef_file, zinfo, zd) + + # set universal newlines on ZipExtFile if necessary + if "U" in mode: + zef.set_univ_newlines(True) + return zef + + def extract(self, member, path=None, pwd=None): + """Extract a member from the archive to the current working directory, + using its full name. Its file information is extracted as accurately + as possible. `member' may be a filename or a ZipInfo object. You can + specify a different directory using `path'. + """ + if not isinstance(member, ZipInfo): + member = self.getinfo(member) + + if path is None: + path = os.getcwd() + + return self._extract_member(member, path, pwd) + + def extractall(self, path=None, members=None, pwd=None): + """Extract all members from the archive to the current working + directory. `path' specifies a different directory to extract to. + `members' is optional and must be a subset of the list returned + by namelist(). + """ + if members is None: + members = self.namelist() + + for zipinfo in members: + self.extract(zipinfo, path, pwd) + + def _extract_member(self, member, targetpath, pwd): + """Extract the ZipInfo object 'member' to a physical + file on the path targetpath. + """ + # build the destination pathname, replacing + # forward slashes to platform specific separators. + if targetpath[-1:] == "/": + targetpath = targetpath[:-1] + + # don't include leading "/" from file name if present + if os.path.isabs(member.filename): + targetpath = os.path.join(targetpath, member.filename[1:]) + else: + targetpath = os.path.join(targetpath, member.filename) + + targetpath = os.path.normpath(targetpath) + + # Create all upper directories if necessary. + upperdirs = os.path.dirname(targetpath) + if upperdirs and not os.path.exists(upperdirs): + os.makedirs(upperdirs) + + source = self.open(member, pwd=pwd) + target = file(targetpath, "wb") + shutil.copyfileobj(source, target) + source.close() + target.close() + + return targetpath def _writecheck(self, zinfo): """Check for errors before writing a file to the archive.""" @@ -616,6 +1065,10 @@ class ZipFile: def write(self, filename, arcname=None, compress_type=None): """Put the bytes from filename into the archive under the name arcname.""" + if not self.fp: + raise RuntimeError( + "Attempt to write to ZIP archive that was already closed") + st = os.stat(filename) mtime = time.localtime(st.st_mtime) date_time = mtime[0:6] @@ -654,7 +1107,7 @@ class ZipFile: if not buf: break file_size = file_size + len(buf) - CRC = binascii.crc32(buf, CRC) + CRC = crc32(buf, CRC) & 0xffffffff if cmpr: buf = cmpr.compress(buf) compress_size = compress_size + len(buf) @@ -672,7 +1125,7 @@ class ZipFile: # Seek backwards and write CRC and file sizes position = self.fp.tell() # Preserve current position in file self.fp.seek(zinfo.header_offset + 14, 0) - self.fp.write(struct.pack(" ZIP64_LIMIT: extra.append(zinfo.file_size) extra.append(zinfo.compress_size) - file_size = 0xffffffff #-1 - compress_size = 0xffffffff #-1 + file_size = 0xffffffff + compress_size = 0xffffffff else: file_size = zinfo.file_size compress_size = zinfo.compress_size if zinfo.header_offset > ZIP64_LIMIT: extra.append(zinfo.header_offset) - header_offset = -1 # struct "l" format: 32 one bits + header_offset = 0xffffffffL else: header_offset = zinfo.header_offset @@ -750,7 +1209,7 @@ class ZipFile: if extra: # Append a ZIP64 field to the extra's extra_data = struct.pack( - '>sys.stderr, (structCentralDir, + stringCentralDir, create_version, + zinfo.create_system, extract_version, zinfo.reserved, + zinfo.flag_bits, zinfo.compress_type, dostime, dosdate, + zinfo.CRC, compress_size, file_size, + len(zinfo.filename), len(extra_data), len(zinfo.comment), + 0, zinfo.internal_attr, zinfo.external_attr, + header_offset) + raise self.fp.write(centdir) - self.fp.write(zinfo.filename) + self.fp.write(filename) self.fp.write(extra_data) self.fp.write(zinfo.comment) pos2 = self.fp.tell() # Write end-of-zip-archive record + centDirOffset = pos1 if pos1 > ZIP64_LIMIT: # Need to write the ZIP64 end-of-archive records zip64endrec = struct.pack( @@ -785,16 +1257,24 @@ class ZipFile: structEndArchive64Locator, stringEndArchive64Locator, 0, pos2, 1) self.fp.write(zip64locrec) + centDirOffset = 0xFFFFFFFF - endrec = struct.pack(structEndArchive, stringEndArchive, - 0, 0, count, count, pos2 - pos1, -1, 0) - self.fp.write(endrec) + # check for valid comment length + if len(self.comment) >= ZIP_MAX_COMMENT: + if self.debug > 0: + msg = 'Archive comment is too long; truncating to %d bytes' \ + % ZIP_MAX_COMMENT + print msg + self.comment = self.comment[:ZIP_MAX_COMMENT] - else: - endrec = struct.pack(structEndArchive, stringEndArchive, - 0, 0, count, count, pos2 - pos1, pos1, 0) - self.fp.write(endrec) + endrec = struct.pack(structEndArchive, stringEndArchive, + 0, 0, count % ZIP_FILECOUNT_LIMIT, + count % ZIP_FILECOUNT_LIMIT, pos2 - pos1, + centDirOffset, len(self.comment)) + self.fp.write(endrec) + self.fp.write(self.comment) self.fp.flush() + if not self._filePassed: self.fp.close() self.fp = None From fc5dbaab4769b969e00cb78e4e6ccf6b7d20c27c Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 30 Jul 2008 08:52:42 -0700 Subject: [PATCH 28/34] Intial implementation of comic2lrf for converting CBR, CBZ files --- src/calibre/__init__.py | 6 +- src/calibre/ebooks/lrf/comic/__init__.py | 16 + src/calibre/ebooks/lrf/comic/convert_from.py | 298 ++ src/calibre/libunzip.py | 34 +- src/calibre/linux.py | 3 + src/calibre/manual/faq.rst | 1 + src/calibre/utils/PythonMagickWand.py | 4360 ++++++++++++++++++ src/calibre/utils/fontconfig.py | 2 +- src/calibre/{ => utils}/terminfo.py | 56 +- src/calibre/{ => utils}/threadpool.py | 0 src/calibre/web/feeds/main.py | 26 +- src/calibre/web/feeds/news.py | 2 +- 12 files changed, 4722 insertions(+), 82 deletions(-) create mode 100644 src/calibre/ebooks/lrf/comic/__init__.py create mode 100755 src/calibre/ebooks/lrf/comic/convert_from.py create mode 100755 src/calibre/utils/PythonMagickWand.py rename src/calibre/{ => utils}/terminfo.py (83%) rename src/calibre/{ => utils}/threadpool.py (100%) diff --git a/src/calibre/__init__.py b/src/calibre/__init__.py index be12f3d102..2dc9ad1a6b 100644 --- a/src/calibre/__init__.py +++ b/src/calibre/__init__.py @@ -20,7 +20,7 @@ from PyQt4.QtGui import QDesktopServices from calibre.translations.msgfmt import make from calibre.ebooks.chardet import detect -from calibre.terminfo import TerminalController +from calibre.utils.terminfo import TerminalController terminal_controller = TerminalController(sys.stdout) iswindows = 'win32' in sys.platform.lower() or 'win64' in sys.platform.lower() @@ -303,10 +303,10 @@ def filename_to_utf8(name): def extract(path, dir): ext = os.path.splitext(path)[1][1:].lower() extractor = None - if ext == 'zip': + if ext in ['zip', 'cbz', 'epub']: from calibre.libunzip import extract as zipextract extractor = zipextract - elif ext == 'rar': + elif ext in ['cbr', 'rar']: from calibre.libunrar import extract as rarextract extractor = rarextract if extractor is None: diff --git a/src/calibre/ebooks/lrf/comic/__init__.py b/src/calibre/ebooks/lrf/comic/__init__.py new file mode 100644 index 0000000000..9ab17a060f --- /dev/null +++ b/src/calibre/ebooks/lrf/comic/__init__.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python +__license__ = 'GPL v3' +__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' +__docformat__ = 'restructuredtext en' + +''' +Convert CBR/CBZ files to LRF. +''' + +import sys + +def main(args=sys.argv): + return 0 + +if __name__ == '__main__': + sys.exit(main()) \ No newline at end of file diff --git a/src/calibre/ebooks/lrf/comic/convert_from.py b/src/calibre/ebooks/lrf/comic/convert_from.py new file mode 100755 index 0000000000..2462253f7c --- /dev/null +++ b/src/calibre/ebooks/lrf/comic/convert_from.py @@ -0,0 +1,298 @@ +#!/usr/bin/env python +__license__ = 'GPL v3' +__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' +__docformat__ = 'restructuredtext en' + +''' +Based on ideas from comiclrf created by FangornUK. +''' + +import os, sys, traceback, shutil +from uuid import uuid4 + +from calibre import extract, OptionParser, detect_ncpus, terminal_controller, \ + __appname__, __version__ +from calibre.ptempfile import PersistentTemporaryDirectory +from calibre.utils.threadpool import ThreadPool, WorkRequest +from calibre.utils.terminfo import ProgressBar +from calibre.ebooks.lrf.pylrs.pylrs import Book, BookSetting, ImageStream, ImageBlock +from calibre.utils.PythonMagickWand import \ + NewMagickWand, NewPixelWand, \ + MagickSetImageBorderColor, \ + MagickReadImage, MagickRotateImage, \ + MagickTrimImage, \ + MagickNormalizeImage, MagickGetImageWidth, \ + MagickGetImageHeight, \ + MagickResizeImage, MagickSetImageType, \ + GrayscaleType, CatromFilter, MagickSetImagePage, \ + MagickBorderImage, MagickSharpenImage, \ + MagickQuantizeImage, RGBColorspace, \ + MagickWriteImage, DestroyPixelWand, \ + DestroyMagickWand, CloneMagickWand, \ + MagickThumbnailImage, MagickCropImage, initialize, finalize + +PROFILES = { + 'prs500':(584, 754), + } + +def extract_comic(path_to_comic_file): + tdir = PersistentTemporaryDirectory(suffix='comic_extract') + extract(path_to_comic_file, tdir) + return tdir + +def find_pages(dir, sort_on_mtime=False, verbose=False): + extensions = ['jpeg', 'jpg', 'gif', 'png'] + pages = [] + for datum in os.walk(dir): + for name in datum[-1]: + path = os.path.join(datum[0], name) + for ext in extensions: + if path.lower().endswith('.'+ext): + pages.append(path) + break + if sort_on_mtime: + comparator = lambda x, y : cmp(os.stat(x).st_mtime, os.stat(y).st_mtime) + else: + comparator = lambda x, y : cmp(os.path.basename(x), os.path.basename(y)) + + pages.sort(cmp=comparator) + if verbose: + print 'Found comic pages...' + print '\t'+'\n\t'.join([os.path.basename(p) for p in pages]) + return pages + +class PageProcessor(list): + + def __init__(self, path_to_page, dest, opts, num): + self.path_to_page = path_to_page + self.opts = opts + self.num = num + self.dest = dest + self.rotate = False + list.__init__(self) + + def __call__(self): + try: + img = NewMagickWand() + if img < 0: + raise RuntimeError('Cannot create wand.') + if not MagickReadImage(img, self.path_to_page): + raise IOError('Failed to read image from: %'%self.path_to_page) + width = MagickGetImageWidth(img) + height = MagickGetImageHeight(img) + + if self.num == 0: # First image so create a thumbnail from it + thumb = CloneMagickWand(img) + if thumb < 0: + raise RuntimeError('Cannot create wand.') + MagickThumbnailImage(thumb, 60, 80) + MagickWriteImage(thumb, os.path.join(self.dest, 'thumbnail.png')) + DestroyMagickWand(thumb) + + self.pages = [img] + + if width > height: + if self.opts.landscape: + self.rotate = True + else: + split1, split2 = map(CloneMagickWand, (img, img)) + if split1 < 0 or split2 < 0: + raise RuntimeError('Cannot create wand.') + DestroyMagickWand(img) + MagickCropImage(split1, (width/2)-1, height, 0, 0) + MagickCropImage(split2, (width/2)-1, height, width/2, 0 ) + self.pages = [split1, split2] + + self.process_pages() + except Exception, err: + print 'Failed to process page: %s'%os.path.basename(self.path_to_page) + print 'Error:', err + if self.opts.verbose: + traceback.print_exc() + + def process_pages(self): + for i, wand in enumerate(self.pages): + pw = NewPixelWand() + if pw < 0: + raise RuntimeError('Cannot create wand.') + #flag = PixelSetColor(pw, 'white') + + MagickSetImageBorderColor(wand, pw) + + if self.rotate: + MagickRotateImage(wand, pw, -90) + + # 25 percent fuzzy trim? + MagickTrimImage(wand, 25*65535/100) + MagickSetImagePage(wand, 0,0,0,0) #Clear page after trim, like a "+repage" + + # Do the Photoshop "Auto Levels" equivalent + if self.opts.normalize: + MagickNormalizeImage(wand) + + sizex = MagickGetImageWidth(wand) + sizey = MagickGetImageHeight(wand) + + SCRWIDTH, SCRHEIGHT = PROFILES[self.opts.profile] + + if self.opts.keep_aspect_ratio: + # Preserve the aspect ratio by adding border + aspect = float(sizex) / float(sizey) + if aspect <= (float(SCRWIDTH) / float(SCRHEIGHT)): + newsizey = SCRHEIGHT + newsizex = int(newsizey * aspect) + deltax = (SCRWIDTH - newsizex) / 2 + deltay = 0 + else: + newsizex = SCRWIDTH + newsizey = int(newsizex / aspect) + deltax = 0 + deltay = (SCRHEIGHT - newsizey) / 2 + + MagickResizeImage(wand, newsizex, newsizey, CatromFilter, 1.0) + MagickSetImageBorderColor(wand, pw) + MagickBorderImage(wand, pw, deltax, deltay) + else: + MagickResizeImage(wand, SCRWIDTH, SCRHEIGHT, CatromFilter, 1.0) + + if self.opts.sharpen: + MagickSharpenImage(wand, 0.0, 1.0) + + MagickSetImageType(wand, GrayscaleType) + MagickQuantizeImage(wand, self.opts.colors, RGBColorspace, 0, 1, 0) + dest = '%d_%d%s'%(self.num, i, os.path.splitext(self.path_to_page)[-1]) + dest = os.path.join(self.dest, dest) + MagickWriteImage(wand, dest) + self.append(dest) + + DestroyPixelWand(pw) + wand = DestroyMagickWand(wand) + +class Progress(object): + + def __init__(self, total, update): + self.total = total + self.update = update + self.done = 0 + + def __call__(self, req, res): + self.done += 1 + self.update(float(self.done)/self.total, + _('Rendered %s')%os.path.basename(req.callable.path_to_page)) + +def process_pages(pages, opts, update): + initialize() + try: + tdir = PersistentTemporaryDirectory('_comic2lrf_pp') + processed_pages = [PageProcessor(path, tdir, opts, i) for i, path in enumerate(pages)] + tp = ThreadPool(detect_ncpus()) + update(0, '') + notify = Progress(len(pages), update) + for pp in processed_pages: + tp.putRequest(WorkRequest(pp, callback=notify)) + tp.wait() + ans, failures = [], [] + + for pp in processed_pages: + if len(pp) == 0: + failures.append(os.path.basename(pp.path_to_page())) + else: + ans += pp + return ans, failures, tdir + finally: + finalize() + +def option_parser(): + parser = OptionParser(_('''\ +%prog [options] comic.cb[z|r] + +Convert a comic in a CBZ or CBR file to an LRF ebook. + ''')) + parser.add_option('-t', '--title', help=_('Title for generated ebook. Default is to use the filename.'), default=None) + parser.add_option('-a', '--author', help=_('Set the author in the metadata of the generated ebook. Default is %default'), default=_('Unknown')) + parser.add_option('-o', '--output', help=_('Path to output LRF file. By default a file is created in the current directory.'), default=None) + parser.add_option('-c', '--colors', type='int', default=64, + help=_('Number of colors for Grayscale image conversion. Default: %default')) + parser.add_option('-n', '--disable-normalize', dest='normalize', default=True, action='store_false', + help=_('Disable normalize (improve contrast) color range for pictures. Default: False')) + parser.add_option('-r', '--keep-aspect-ratio', action='store_true', default=False, + help=_('Maintain picture aspect ratio. Default is to fill the screen.')) + parser.add_option('-s', '--disable-sharpen', default=True, action='store_false', dest='sharpen', + help=_('Disable sharpening.')) + parser.add_option('-l', '--landscape', default=False, action='store_true', + help=_("Don't split landscape images into two portrait images")) + parser.add_option('--no-sort', default=False, action='store_true', + help=_("Don't sort the files found in the comic alphabetically by name. Instead use the order they were added to the comic.")) + parser.add_option('-p', '--profile', default='prs500', dest='profile', type='choice', + choices=PROFILES.keys(), help=_('Choose a profile for the device you are generating this LRF for. The default is the SONY PRS-500 with a screen size of 584x754 pixels. Choices are %s')%PROFILES.keys()) + parser.add_option('--verbose', default=False, action='store_true', + help=_('Be verbose, useful for debugging')) + parser.add_option('--no-progress-bar', default=False, action='store_true', + help=_("Don't show progress bar.")) + return parser + +def create_lrf(pages, profile, opts, thumbnail=None): + width, height = PROFILES[profile] + ps = {} + ps['topmargin'] = 0 + ps['evensidemargin'] = 0 + ps['oddsidemargin'] = 0 + ps['textwidth'] = width + ps['textheight'] = height + book = Book(title=opts.title, author=opts.author, + bookid=uuid4().hex, + publisher='%s %s'%(__appname__, __version__), thumbnail=thumbnail, + category='Comic', pagestyledefault=ps, + booksetting=BookSetting(screenwidth=width, screenheight=height)) + for page in pages: + imageStream = ImageStream(page) + _page = book.create_page() + _page.append(ImageBlock(refstream=imageStream, + blockwidth=width, blockheight=height, xsize=width, + ysize=height, x1=width, y1=height)) + book.append(_page) + + book.renderLrf(open(opts.output, 'wb')) + + + +def main(args=sys.argv, notification=None): + parser = option_parser() + opts, args = parser.parse_args(args) + if len(args) < 2: + parser.print_help() + print '\nYou must specify a file to convert' + return 1 + + if not callable(notification): + pb = ProgressBar(terminal_controller, _('Rendering comic pages...'), + no_progress_bar=opts.no_progress_bar) + notification = pb.update + + source = os.path.abspath(args[1]) + if not opts.title: + opts.title = os.path.splitext(os.path.basename(source)) + if not opts.output: + opts.output = os.path.abspath(os.path.splitext(os.path.basename(source))[0]+'.lrf') + + tdir = extract_comic(source) + pages = find_pages(tdir, sort_on_mtime=opts.no_sort, verbose=opts.verbose) + if not pages: + raise ValueError('Could not find any pages in the comic: %s'%source) + pages, failures, tdir2 = process_pages(pages, opts, notification) + if not pages: + raise ValueError('Could not find any valid pages in the comic: %s'%source) + if failures: + print 'Could not process the following pages (run with --verbose to see why):' + for f in failures: + print '\t', f + thumbnail = os.path.join(tdir2, 'thumbnail.png') + if not os.access(thumbnail, os.R_OK): + thumbnail = None + create_lrf(pages, opts.profile, opts, thumbnail=thumbnail) + shutil.rmtree(tdir) + shutil.rmtree(tdir2) + return 0 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/calibre/libunzip.py b/src/calibre/libunzip.py index 2c24067f7a..aec7865ffb 100644 --- a/src/calibre/libunzip.py +++ b/src/calibre/libunzip.py @@ -3,8 +3,6 @@ __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __docformat__ = 'restructuredtext en' -import os -from cStringIO import StringIO from calibre.utils import zipfile def update(pathtozip, patterns, filepaths, names, compression=zipfile.ZIP_DEFLATED, verbose=True): @@ -42,34 +40,4 @@ def extract(filename, dir): Extract archive C{filename} into directory C{dir} """ zf = zipfile.ZipFile( filename ) - namelist = zf.namelist() - dirlist = filter( lambda x: x.endswith( '/' ), namelist ) - filelist = filter( lambda x: not x.endswith( '/' ), namelist ) - # make base - pushd = os.getcwd() - if not os.path.isdir( dir ): - os.mkdir( dir ) - os.chdir( dir ) - # create directory structure - dirlist.sort() - for dirs in dirlist: - dirs = dirs.split( '/' ) - prefix = '' - for dir in dirs: - dirname = os.path.join( prefix, dir ) - if dir and not os.path.isdir( dirname ): - os.mkdir( dirname ) - prefix = dirname - # extract files - for fn in filelist: - if os.path.dirname(fn) and not os.path.exists(os.path.dirname(fn)): - os.makedirs(os.path.dirname(fn)) - out = open( fn, 'wb' ) - buffer = StringIO( zf.read( fn )) - buflen = 2 ** 20 - datum = buffer.read( buflen ) - while datum: - out.write( datum ) - datum = buffer.read( buflen ) - out.close() - os.chdir( pushd ) \ No newline at end of file + zf.extractall(dir) \ No newline at end of file diff --git a/src/calibre/linux.py b/src/calibre/linux.py index 1cb0a1ff81..b55f02c15e 100644 --- a/src/calibre/linux.py +++ b/src/calibre/linux.py @@ -47,6 +47,7 @@ entry_points = { 'mobi2oeb = calibre.ebooks.mobi.reader:main', 'lrf2html = calibre.ebooks.lrf.html.convert_to:main', 'lit2oeb = calibre.ebooks.lit.reader:main', + 'comic2lrf = calibre.ebooks.lrf.comic.convert_from:main', 'calibre-debug = calibre.debug:main', 'calibredb = calibre.library.cli:main', 'calibre-fontconfig = calibre.utils.fontconfig:main', @@ -166,6 +167,7 @@ def setup_completion(fatal_errors): from calibre.web.feeds.recipes import titles as feed_titles from calibre.ebooks.lrf.feeds.convert_from import option_parser as feeds2lrf from calibre.ebooks.metadata.epub import option_parser as epub_meta + from calibre.ebooks.lrf.comic.convert_from import option_parser as comicop f = open_file('/etc/bash_completion.d/libprs500') f.close() @@ -198,6 +200,7 @@ def setup_completion(fatal_errors): f.write(opts_and_exts('pdfrelow', pdfhtmlop, ['pdf'])) f.write(opts_and_exts('mobi2oeb', mobioeb, ['mobi', 'prc'])) f.write(opts_and_exts('lit2oeb', lit2oeb, ['lit'])) + f.write(opts_and_exts('comic2lrf', comicop, ['cbz', 'cbr'])) f.write(opts_and_words('feeds2disk', feeds2disk, feed_titles)) f.write(opts_and_words('feeds2lrf', feeds2lrf, feed_titles)) f.write(''' diff --git a/src/calibre/manual/faq.rst b/src/calibre/manual/faq.rst index f2bcbc3022..f35c14d493 100644 --- a/src/calibre/manual/faq.rst +++ b/src/calibre/manual/faq.rst @@ -133,6 +133,7 @@ The graphical user interface of |app| is not starting on Windows? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ There can be several causes for this: + * **Any windows version**: Try running it as Administrator (Right click on the icon ans select "Run as Administrator") * **Any windows version**: Search for the files `calibre2.ini` and `calibre.ini` on your computer and delete them. Search for the file `library1.db` and rename it (this file contains all your converted books so deleting it is not a good idea. Now try again. * **Windows Vista**: If the folder :file:`C:\Users\Your User Name\AppData\Local\VirtualStore\Program Files\calibre` exists, delete it. Uninstall |app|. Reboot. Re-install. * **Any windows version**: Search your computer for a folder named :file:`_ipython`. Delete it and try again. diff --git a/src/calibre/utils/PythonMagickWand.py b/src/calibre/utils/PythonMagickWand.py new file mode 100755 index 0000000000..c0664b3573 --- /dev/null +++ b/src/calibre/utils/PythonMagickWand.py @@ -0,0 +1,4360 @@ +""" +PythonMagickWand - Version 0.1 +(c) 2007 - Achim Domma - domma@procoders.net +http://www.procoders.net + +About +----- + +I still get a lot requests to update PythonMagick, which is based on +boost.python and is too hard to maintain. So I decided to develop a +ctypes based wrapper for the MagickWand API, which should be enough +to do common image manipulation tasks in python. + +Please don't ask questions about how to use the API! I'm not an +ImageMagick expert. Usually I need ImageMagick to do simple things +like resizing of images. You will find mailinglists about ImageMagick +on http://www.imagemagick.org. The documentation of the MagickWand +API can be found on http://www.imagemagick.org/script/magick-wand.php. + +I have not yet decided which license to use, but it will something +like the MIT license. + +Any feedback is very welcome! + +Achim + + +Usage +----- + +Of course you will have to import the PythonMagickWand module. The +ImageMagick library is loaded at that moment and will probably not +be found on your system. + +I'm working on a Mac OS X with macports installed. At the moment you +will have to fix the path on top of PythonMagickWand.py. I'll fix +this in the next release. + + >>> from PythonMagickWand import * + +After that, you have to initialize MagickWand. This call might be +moved to the PythonMagickWand module, but i have to check if there +are poblems with multiple calls to this method or how to handle that. + + >>> MagickWandGenesis() + +Now we are ready to create a new wand + + >>> wand = NewMagickWand() + +and to load an image from a file. + + >>> MagickReadImage(wand,"sample.jpg") #doctest: +ELLIPSIS + + +Let's resize the image + + >>> MagickScaleImage(wand,200,200) #doctest: +ELLIPSIS + + +and save it to a new file. + + >>> MagickWriteImage(wand,"out.png") #doctest: +ELLIPSIS + + >>> + + +""" +import ctypes, sys, os +from ctypes import util +iswindows = 'win32' in sys.platform or 'win64' in sys.platform +isosx = 'darwin' in sys.platform +isfrozen = getattr(sys, 'frozen', False) + +if isosx: + _lib = os.path.join(getattr(sys, 'frameworks_dir'), 'ImageMagick', 'libWand.dylib') \ + if isfrozen else util.find_library('Wand') +elif iswindows: + _lib = os.path.join(os.path.dirname(sys.executable), 'ImageMagick', 'CORE_RL_wand_.dll') \ + if isfrozen else 'CORE_RL_wand_' +else: + _lib = util.find_library('MagickWand') + + + +_magick = _magick_error = None +try: + _magick = ctypes.CDLL(_lib) +except Exception, err: + _magick_erorr = str(err) + +_initialized = False +def initialize(): + global _initialized + if not _initialized: + if _magick is not None and not _initialized: + _magick.MagickWandGenesis() + else: + raise RuntimeError('Failed to load ImageMagick: %s'%_magick_error) + +def finalize(): + global _initialized + if _initialized: + _magick.MagickWandTerminus() + _initialized = False + + +class MetricType(ctypes.c_int): pass +UndefinedMetric = MetricType(0) +AbsoluteErrorMetric = MetricType(1) +MeanAbsoluteErrorMetric = MetricType(2) +MeanErrorPerPixelMetric = MetricType(3) +MeanSquaredErrorMetric = MetricType(4) +PeakAbsoluteErrorMetric = MetricType(5) +PeakSignalToNoiseRatioMetric = MetricType(6) +RootMeanSquaredErrorMetric = MetricType(7) + +class NoiseType(ctypes.c_int): pass +UndefinedNoise = NoiseType(0) +UniformNoise = NoiseType(1) +GaussianNoise = NoiseType(2) +MultiplicativeGaussianNoise = NoiseType(3) +ImpulseNoise = NoiseType(4) +LaplacianNoise = NoiseType(5) +PoissonNoise = NoiseType(6) +RandomNoise = NoiseType(7) + +class ImageLayerMethod(ctypes.c_int): pass +UndefinedLayer = ImageLayerMethod(0) +CoalesceLayer = ImageLayerMethod(1) +CompareAnyLayer = ImageLayerMethod(2) +CompareClearLayer = ImageLayerMethod(3) +CompareOverlayLayer = ImageLayerMethod(4) +DisposeLayer = ImageLayerMethod(5) +OptimizeLayer = ImageLayerMethod(6) +OptimizeImageLayer = ImageLayerMethod(7) +OptimizePlusLayer = ImageLayerMethod(8) +OptimizeTransLayer = ImageLayerMethod(9) +RemoveDupsLayer = ImageLayerMethod(10) +RemoveZeroLayer = ImageLayerMethod(11) +CompositeLayer = ImageLayerMethod(12) +MergeLayer = ImageLayerMethod(13) +FlattenLayer = ImageLayerMethod(14) +MosaicLayer = ImageLayerMethod(15) + +class MagickOption(ctypes.c_int): pass +MagickUndefinedOptions = MagickOption(-1) +MagickAlignOptions = MagickOption(0) +MagickAlphaOptions = MagickOption(1) +MagickBooleanOptions = MagickOption(2) +MagickChannelOptions = MagickOption(3) +MagickClassOptions = MagickOption(4) +MagickClipPathOptions = MagickOption(5) +MagickColorspaceOptions = MagickOption(6) +MagickCommandOptions = MagickOption(7) +MagickComposeOptions = MagickOption(8) +MagickCompressOptions = MagickOption(9) +MagickDataTypeOptions = MagickOption(10) +MagickDebugOptions = MagickOption(11) +MagickDecorateOptions = MagickOption(12) +MagickDisposeOptions = MagickOption(13) +MagickDistortOptions = MagickOption(14) +MagickEndianOptions = MagickOption(15) +MagickEvaluateOptions = MagickOption(16) +MagickFillRuleOptions = MagickOption(17) +MagickFilterOptions = MagickOption(18) +MagickFontsOptions = MagickOption(19) +MagickGravityOptions = MagickOption(20) +MagickIntentOptions = MagickOption(21) +MagickInterlaceOptions = MagickOption(22) +MagickInterpolateOptions = MagickOption(23) +MagickLayerOptions = MagickOption(24) +MagickLineCapOptions = MagickOption(25) +MagickLineJoinOptions = MagickOption(26) +MagickListOptions = MagickOption(27) +MagickLogEventOptions = MagickOption(28) +MagickMetricOptions = MagickOption(29) +MagickMethodOptions = MagickOption(30) +MagickModeOptions = MagickOption(31) +MagickMogrifyOptions = MagickOption(32) +MagickNoiseOptions = MagickOption(33) +MagickOrientationOptions = MagickOption(34) +MagickPreviewOptions = MagickOption(35) +MagickPrimitiveOptions = MagickOption(36) +MagickQuantumFormatOptions = MagickOption(37) +MagickResolutionOptions = MagickOption(38) +MagickResourceOptions = MagickOption(39) +MagickStorageOptions = MagickOption(40) +MagickStretchOptions = MagickOption(41) +MagickStyleOptions = MagickOption(42) +MagickTypeOptions = MagickOption(43) +MagickVirtualPixelOptions = MagickOption(44) +MagickCoderOptions = MagickOption(45) +MagickColorOptions = MagickOption(46) +MagickConfigureOptions = MagickOption(47) +MagickDelegateOptions = MagickOption(48) +MagickFontOptions = MagickOption(49) +MagickFormatOptions = MagickOption(50) +MagickMimeOptions = MagickOption(51) +MagickLocaleOptions = MagickOption(52) +MagickLogOptions = MagickOption(53) +MagickMagicOptions = MagickOption(54) +MagickModuleOptions = MagickOption(55) +MagickThresholdOptions = MagickOption(56) + +class StretchType(ctypes.c_int): pass +UndefinedStretch = StretchType(0) +NormalStretch = StretchType(1) +UltraCondensedStretch = StretchType(2) +ExtraCondensedStretch = StretchType(3) +CondensedStretch = StretchType(4) +SemiCondensedStretch = StretchType(5) +SemiExpandedStretch = StretchType(6) +ExpandedStretch = StretchType(7) +ExtraExpandedStretch = StretchType(8) +UltraExpandedStretch = StretchType(9) +AnyStretch = StretchType(10) + +class StyleType(ctypes.c_int): pass +UndefinedStyle = StyleType(0) +NormalStyle = StyleType(1) +ItalicStyle = StyleType(2) +ObliqueStyle = StyleType(3) +AnyStyle = StyleType(4) + +class LineJoin(ctypes.c_int): pass +UndefinedJoin = LineJoin(0) +MiterJoin = LineJoin(1) +RoundJoin = LineJoin(2) +BevelJoin = LineJoin(3) + +class PaintMethod(ctypes.c_int): pass +UndefinedMethod = PaintMethod(0) +PointMethod = PaintMethod(1) +ReplaceMethod = PaintMethod(2) +FloodfillMethod = PaintMethod(3) +FillToBorderMethod = PaintMethod(4) +ResetMethod = PaintMethod(5) + +class AlphaChannelType(ctypes.c_int): pass +UndefinedAlphaChannel = AlphaChannelType(0) +ActivateAlphaChannel = AlphaChannelType(1) +DeactivateAlphaChannel = AlphaChannelType(2) +ResetAlphaChannel = AlphaChannelType(3) +SetAlphaChannel = AlphaChannelType(4) + +class CompositeOperator(ctypes.c_int): pass +UndefinedCompositeOp = CompositeOperator(0) +NoCompositeOp = CompositeOperator(1) +AddCompositeOp = CompositeOperator(2) +AtopCompositeOp = CompositeOperator(3) +BlendCompositeOp = CompositeOperator(4) +BumpmapCompositeOp = CompositeOperator(5) +ChangeMaskCompositeOp = CompositeOperator(6) +ClearCompositeOp = CompositeOperator(7) +ColorBurnCompositeOp = CompositeOperator(8) +ColorDodgeCompositeOp = CompositeOperator(9) +ColorizeCompositeOp = CompositeOperator(10) +CopyBlackCompositeOp = CompositeOperator(11) +CopyBlueCompositeOp = CompositeOperator(12) +CopyCompositeOp = CompositeOperator(13) +CopyCyanCompositeOp = CompositeOperator(14) +CopyGreenCompositeOp = CompositeOperator(15) +CopyMagentaCompositeOp = CompositeOperator(16) +CopyOpacityCompositeOp = CompositeOperator(17) +CopyRedCompositeOp = CompositeOperator(18) +CopyYellowCompositeOp = CompositeOperator(19) +DarkenCompositeOp = CompositeOperator(20) +DstAtopCompositeOp = CompositeOperator(21) +DstCompositeOp = CompositeOperator(22) +DstInCompositeOp = CompositeOperator(23) +DstOutCompositeOp = CompositeOperator(24) +DstOverCompositeOp = CompositeOperator(25) +DifferenceCompositeOp = CompositeOperator(26) +DisplaceCompositeOp = CompositeOperator(27) +DissolveCompositeOp = CompositeOperator(28) +ExclusionCompositeOp = CompositeOperator(29) +HardLightCompositeOp = CompositeOperator(30) +HueCompositeOp = CompositeOperator(31) +InCompositeOp = CompositeOperator(32) +LightenCompositeOp = CompositeOperator(33) +LinearLightCompositeOp = CompositeOperator(34) +LuminizeCompositeOp = CompositeOperator(35) +MinusCompositeOp = CompositeOperator(36) +ModulateCompositeOp = CompositeOperator(37) +MultiplyCompositeOp = CompositeOperator(38) +OutCompositeOp = CompositeOperator(39) +OverCompositeOp = CompositeOperator(40) +OverlayCompositeOp = CompositeOperator(41) +PlusCompositeOp = CompositeOperator(42) +ReplaceCompositeOp = CompositeOperator(43) +SaturateCompositeOp = CompositeOperator(44) +ScreenCompositeOp = CompositeOperator(45) +SoftLightCompositeOp = CompositeOperator(46) +SrcAtopCompositeOp = CompositeOperator(47) +SrcCompositeOp = CompositeOperator(48) +SrcInCompositeOp = CompositeOperator(49) +SrcOutCompositeOp = CompositeOperator(50) +SrcOverCompositeOp = CompositeOperator(51) +SubtractCompositeOp = CompositeOperator(52) +ThresholdCompositeOp = CompositeOperator(53) +XorCompositeOp = CompositeOperator(54) +DivideCompositeOp = CompositeOperator(55) + +class CompressionType(ctypes.c_int): pass +UndefinedCompression = CompressionType(0) +NoCompression = CompressionType(1) +BZipCompression = CompressionType(2) +FaxCompression = CompressionType(3) +Group4Compression = CompressionType(4) +JPEGCompression = CompressionType(5) +JPEG2000Compression = CompressionType(6) +LosslessJPEGCompression = CompressionType(7) +LZWCompression = CompressionType(8) +RLECompression = CompressionType(9) +ZipCompression = CompressionType(10) + +class LineCap(ctypes.c_int): pass +UndefinedCap = LineCap(0) +ButtCap = LineCap(1) +RoundCap = LineCap(2) +SquareCap = LineCap(3) + +class GravityType(ctypes.c_int): pass +UndefinedGravity = GravityType(0) +ForgetGravity = GravityType(0) +NorthWestGravity = GravityType(1) +NorthGravity = GravityType(2) +NorthEastGravity = GravityType(3) +WestGravity = GravityType(4) +CenterGravity = GravityType(5) +EastGravity = GravityType(6) +SouthWestGravity = GravityType(7) +SouthGravity = GravityType(8) +SouthEastGravity = GravityType(9) +StaticGravity = GravityType(10) + +class RegistryType(ctypes.c_int): pass +UndefinedRegistryType = RegistryType(0) +ImageRegistryType = RegistryType(1) +ImageInfoRegistryType = RegistryType(2) +StringRegistryType = RegistryType(3) + +class MontageMode(ctypes.c_int): pass +UndefinedMode = MontageMode(0) +FrameMode = MontageMode(1) +UnframeMode = MontageMode(2) +ConcatenateMode = MontageMode(3) + +class ClipPathUnits(ctypes.c_int): pass +UndefinedPathUnits = ClipPathUnits(0) +UserSpace = ClipPathUnits(1) +UserSpaceOnUse = ClipPathUnits(2) +ObjectBoundingBox = ClipPathUnits(3) + +class AlignType(ctypes.c_int): pass +UndefinedAlign = AlignType(0) +LeftAlign = AlignType(1) +CenterAlign = AlignType(2) +RightAlign = AlignType(3) + +class ResolutionType(ctypes.c_int): pass +UndefinedResolution = ResolutionType(0) +PixelsPerInchResolution = ResolutionType(1) +PixelsPerCentimeterResolution = ResolutionType(2) + +class OrientationType(ctypes.c_int): pass +UndefinedOrientation = OrientationType(0) +TopLeftOrientation = OrientationType(1) +TopRightOrientation = OrientationType(2) +BottomRightOrientation = OrientationType(3) +BottomLeftOrientation = OrientationType(4) +LeftTopOrientation = OrientationType(5) +RightTopOrientation = OrientationType(6) +RightBottomOrientation = OrientationType(7) +LeftBottomOrientation = OrientationType(8) + +class InterlaceType(ctypes.c_int): pass +UndefinedInterlace = InterlaceType(0) +NoInterlace = InterlaceType(1) +LineInterlace = InterlaceType(2) +PlaneInterlace = InterlaceType(3) +PartitionInterlace = InterlaceType(4) +GIFInterlace = InterlaceType(5) +JPEGInterlace = InterlaceType(6) +PNGInterlace = InterlaceType(7) + +class ImageType(ctypes.c_int): pass +UndefinedType = ImageType(0) +BilevelType = ImageType(1) +GrayscaleType = ImageType(2) +GrayscaleMatteType = ImageType(3) +PaletteType = ImageType(4) +PaletteMatteType = ImageType(5) +TrueColorType = ImageType(6) +TrueColorMatteType = ImageType(7) +ColorSeparationType = ImageType(8) +ColorSeparationMatteType = ImageType(9) +OptimizeType = ImageType(10) +PaletteBilevelMatteType = ImageType(11) + +class LogEventType(ctypes.c_int): pass +UndefinedEvents = LogEventType(0) +NoEvents = LogEventType(0) +TraceEvent = LogEventType(1) +AnnotateEvent = LogEventType(2) +BlobEvent = LogEventType(4) +CacheEvent = LogEventType(8) +CoderEvent = LogEventType(16) +ConfigureEvent = LogEventType(32) +DeprecateEvent = LogEventType(64) +DrawEvent = LogEventType(128) +ExceptionEvent = LogEventType(256) +LocaleEvent = LogEventType(512) +ModuleEvent = LogEventType(1024) +ResourceEvent = LogEventType(2048) +TransformEvent = LogEventType(4096) +UserEvent = LogEventType(8192) +WandEvent = LogEventType(16384) +X11Event = LogEventType(32768) +AllEvents = LogEventType(2147483647) + +class StorageType(ctypes.c_int): pass +UndefinedPixel = StorageType(0) +CharPixel = StorageType(1) +DoublePixel = StorageType(2) +FloatPixel = StorageType(3) +IntegerPixel = StorageType(4) +LongPixel = StorageType(5) +QuantumPixel = StorageType(6) +ShortPixel = StorageType(7) + +class ColorspaceType(ctypes.c_int): pass +UndefinedColorspace = ColorspaceType(0) +RGBColorspace = ColorspaceType(1) +GRAYColorspace = ColorspaceType(2) +TransparentColorspace = ColorspaceType(3) +OHTAColorspace = ColorspaceType(4) +LabColorspace = ColorspaceType(5) +XYZColorspace = ColorspaceType(6) +YCbCrColorspace = ColorspaceType(7) +YCCColorspace = ColorspaceType(8) +YIQColorspace = ColorspaceType(9) +YPbPrColorspace = ColorspaceType(10) +YUVColorspace = ColorspaceType(11) +CMYKColorspace = ColorspaceType(12) +sRGBColorspace = ColorspaceType(13) +HSBColorspace = ColorspaceType(14) +HSLColorspace = ColorspaceType(15) +HWBColorspace = ColorspaceType(16) +Rec601LumaColorspace = ColorspaceType(17) +Rec601YCbCrColorspace = ColorspaceType(18) +Rec709LumaColorspace = ColorspaceType(19) +Rec709YCbCrColorspace = ColorspaceType(20) +LogColorspace = ColorspaceType(21) +CMYColorspace = ColorspaceType(22) + +class InterpolatePixelMethod(ctypes.c_int): pass +UndefinedInterpolatePixel = InterpolatePixelMethod(0) +AverageInterpolatePixel = InterpolatePixelMethod(1) +BicubicInterpolatePixel = InterpolatePixelMethod(2) +BilinearInterpolatePixel = InterpolatePixelMethod(3) +FilterInterpolatePixel = InterpolatePixelMethod(4) +IntegerInterpolatePixel = InterpolatePixelMethod(5) +MeshInterpolatePixel = InterpolatePixelMethod(6) +NearestNeighborInterpolatePixel = InterpolatePixelMethod(7) +SplineInterpolatePixel = InterpolatePixelMethod(8) + +class MagickEvaluateOperator(ctypes.c_int): pass +UndefinedEvaluateOperator = MagickEvaluateOperator(0) +AddEvaluateOperator = MagickEvaluateOperator(1) +AndEvaluateOperator = MagickEvaluateOperator(2) +DivideEvaluateOperator = MagickEvaluateOperator(3) +LeftShiftEvaluateOperator = MagickEvaluateOperator(4) +MaxEvaluateOperator = MagickEvaluateOperator(5) +MinEvaluateOperator = MagickEvaluateOperator(6) +MultiplyEvaluateOperator = MagickEvaluateOperator(7) +OrEvaluateOperator = MagickEvaluateOperator(8) +RightShiftEvaluateOperator = MagickEvaluateOperator(9) +SetEvaluateOperator = MagickEvaluateOperator(10) +SubtractEvaluateOperator = MagickEvaluateOperator(11) +XorEvaluateOperator = MagickEvaluateOperator(12) + +class ExceptionType(ctypes.c_int): + pass + +UndefinedException = ExceptionType(0) +WarningException = ExceptionType(300) +ResourceLimitWarning = ExceptionType(300) +TypeWarning = ExceptionType(305) +OptionWarning = ExceptionType(310) +DelegateWarning = ExceptionType(315) +MissingDelegateWarning = ExceptionType(320) +CorruptImageWarning = ExceptionType(325) +FileOpenWarning = ExceptionType(330) +BlobWarning = ExceptionType(335) +StreamWarning = ExceptionType(340) +CacheWarning = ExceptionType(345) +CoderWarning = ExceptionType(350) +ModuleWarning = ExceptionType(355) +DrawWarning = ExceptionType(360) +ImageWarning = ExceptionType(365) +WandWarning = ExceptionType(370) +XServerWarning = ExceptionType(380) +MonitorWarning = ExceptionType(385) +RegistryWarning = ExceptionType(390) +ConfigureWarning = ExceptionType(395) +ErrorException = ExceptionType(400) +ResourceLimitError = ExceptionType(400) +TypeError = ExceptionType(405) +OptionError = ExceptionType(410) +DelegateError = ExceptionType(415) +MissingDelegateError = ExceptionType(420) +CorruptImageError = ExceptionType(425) +FileOpenError = ExceptionType(430) +BlobError = ExceptionType(435) +StreamError = ExceptionType(440) +CacheError = ExceptionType(445) +CoderError = ExceptionType(450) +ModuleError = ExceptionType(455) +DrawError = ExceptionType(460) +ImageError = ExceptionType(465) +WandError = ExceptionType(470) +XServerError = ExceptionType(480) +MonitorError = ExceptionType(485) +RegistryError = ExceptionType(490) +ConfigureError = ExceptionType(495) +FatalErrorException = ExceptionType(700) +ResourceLimitFatalError = ExceptionType(700) +TypeFatalError = ExceptionType(705) +OptionFatalError = ExceptionType(710) +DelegateFatalError = ExceptionType(715) +MissingDelegateFatalError = ExceptionType(720) +CorruptImageFatalError = ExceptionType(725) +FileOpenFatalError = ExceptionType(730) +BlobFatalError = ExceptionType(735) +StreamFatalError = ExceptionType(740) +CacheFatalError = ExceptionType(745) +CoderFatalError = ExceptionType(750) +ModuleFatalError = ExceptionType(755) +DrawFatalError = ExceptionType(760) +ImageFatalError = ExceptionType(765) +WandFatalError = ExceptionType(770) +XServerFatalError = ExceptionType(780) +MonitorFatalError = ExceptionType(785) +RegistryFatalError = ExceptionType(790) +ConfigureFatalError = ExceptionType(795) + +class ChannelType(ctypes.c_int): pass +UndefinedChannel = ChannelType(0) +RedChannel = ChannelType(1) +GrayChannel = ChannelType(1) +CyanChannel = ChannelType(1) +GreenChannel = ChannelType(2) +MagentaChannel = ChannelType(2) +BlueChannel = ChannelType(4) +YellowChannel = ChannelType(4) +AlphaChannel = ChannelType(8) +OpacityChannel = ChannelType(8) +MatteChannel = ChannelType(8) +BlackChannel = ChannelType(32) +IndexChannel = ChannelType(32) +AllChannels = ChannelType(255) +DefaultChannels = ChannelType(247) + +class DistortImageMethod(ctypes.c_int): pass +UndefinedDistortion = DistortImageMethod(0) +AffineDistortion = DistortImageMethod(1) +AffineProjectionDistortion = DistortImageMethod(2) +ArcDistortion = DistortImageMethod(3) +BilinearDistortion = DistortImageMethod(4) +PerspectiveDistortion = DistortImageMethod(5) +PerspectiveProjectionDistortion = DistortImageMethod(6) +ScaleRotateTranslateDistortion = DistortImageMethod(7) + +class FillRule(ctypes.c_int): pass +UndefinedRule = FillRule(0) +EvenOddRule = FillRule(1) +NonZeroRule = FillRule(2) + +class DecorationType(ctypes.c_int): pass +UndefinedDecoration = DecorationType(0) +NoDecoration = DecorationType(1) +UnderlineDecoration = DecorationType(2) +OverlineDecoration = DecorationType(3) +LineThroughDecoration = DecorationType(4) + +class FilterTypes(ctypes.c_int): pass +UndefinedFilter = FilterTypes(0) +PointFilter = FilterTypes(1) +BoxFilter = FilterTypes(2) +TriangleFilter = FilterTypes(3) +HermiteFilter = FilterTypes(4) +HanningFilter = FilterTypes(5) +HammingFilter = FilterTypes(6) +BlackmanFilter = FilterTypes(7) +GaussianFilter = FilterTypes(8) +QuadraticFilter = FilterTypes(9) +CubicFilter = FilterTypes(10) +CatromFilter = FilterTypes(11) +MitchellFilter = FilterTypes(12) +LanczosFilter = FilterTypes(13) +BesselFilter = FilterTypes(14) +SincFilter = FilterTypes(15) +KaiserFilter = FilterTypes(16) +WelshFilter = FilterTypes(17) +ParzenFilter = FilterTypes(18) +LagrangeFilter = FilterTypes(19) +BohmanFilter = FilterTypes(20) +BartlettFilter = FilterTypes(21) +SentinelFilter = FilterTypes(22) + +class VirtualPixelMethod(ctypes.c_int): pass +UndefinedVirtualPixelMethod = VirtualPixelMethod(0) +BackgroundVirtualPixelMethod = VirtualPixelMethod(1) +ConstantVirtualPixelMethod = VirtualPixelMethod(2) +DitherVirtualPixelMethod = VirtualPixelMethod(3) +EdgeVirtualPixelMethod = VirtualPixelMethod(4) +MirrorVirtualPixelMethod = VirtualPixelMethod(5) +RandomVirtualPixelMethod = VirtualPixelMethod(6) +TileVirtualPixelMethod = VirtualPixelMethod(7) +TransparentVirtualPixelMethod = VirtualPixelMethod(8) +MaskVirtualPixelMethod = VirtualPixelMethod(9) +BlackVirtualPixelMethod = VirtualPixelMethod(10) +GrayVirtualPixelMethod = VirtualPixelMethod(11) +WhiteVirtualPixelMethod = VirtualPixelMethod(12) + +class DisposeType(ctypes.c_int): pass +UnrecognizedDispose = DisposeType(0) +UndefinedDispose = DisposeType(0) +NoneDispose = DisposeType(1) +BackgroundDispose = DisposeType(2) +PreviousDispose = DisposeType(3) + +class MagickBooleanType(ctypes.c_int): pass +MagickFalse = MagickBooleanType(0) +MagickTrue = MagickBooleanType(1) + +class PreviewType(ctypes.c_int): pass +UndefinedPreview = PreviewType(0) +RotatePreview = PreviewType(1) +ShearPreview = PreviewType(2) +RollPreview = PreviewType(3) +HuePreview = PreviewType(4) +SaturationPreview = PreviewType(5) +BrightnessPreview = PreviewType(6) +GammaPreview = PreviewType(7) +SpiffPreview = PreviewType(8) +DullPreview = PreviewType(9) +GrayscalePreview = PreviewType(10) +QuantizePreview = PreviewType(11) +DespecklePreview = PreviewType(12) +ReduceNoisePreview = PreviewType(13) +AddNoisePreview = PreviewType(14) +SharpenPreview = PreviewType(15) +BlurPreview = PreviewType(16) +ThresholdPreview = PreviewType(17) +EdgeDetectPreview = PreviewType(18) +SpreadPreview = PreviewType(19) +SolarizePreview = PreviewType(20) +ShadePreview = PreviewType(21) +RaisePreview = PreviewType(22) +SegmentPreview = PreviewType(23) +SwirlPreview = PreviewType(24) +ImplodePreview = PreviewType(25) +WavePreview = PreviewType(26) +OilPaintPreview = PreviewType(27) +CharcoalDrawingPreview = PreviewType(28) +JPEGPreview = PreviewType(29) + +class RenderingIntent(ctypes.c_int): pass +UndefinedIntent = RenderingIntent(0) +SaturationIntent = RenderingIntent(1) +PerceptualIntent = RenderingIntent(2) +AbsoluteIntent = RenderingIntent(3) +RelativeIntent = RenderingIntent(4) + +class ResourceType(ctypes.c_int): pass +UndefinedResource = ResourceType(0) +AreaResource = ResourceType(1) +DiskResource = ResourceType(2) +FileResource = ResourceType(3) +MapResource = ResourceType(4) +MemoryResource = ResourceType(5) + + +class ComplianceType(ctypes.c_int): pass +UndefinedCompliance = ComplianceType(0) +NoCompliance = ComplianceType(0) +SVGCompliance = ComplianceType(1) +X11Compliance = ComplianceType(2) +XPMCompliance = ComplianceType(4) +AllCompliance = ComplianceType(2147483647) + +class FILE(ctypes.c_void_p): pass +class MagickPixelPacket(ctypes.c_void_p): pass +class PixelWand(ctypes.c_void_p): pass +class TypeMetric(ctypes.c_void_p): pass +class PrimitiveInfo(ctypes.c_void_p): pass +class size_t(ctypes.c_void_p): pass +class AffineMatrix(ctypes.c_void_p): pass +class DrawInfo(ctypes.c_void_p): pass +class MagickProgressMonitor(ctypes.c_void_p): pass +class PointInfo(ctypes.c_void_p): pass +class DrawingWand(ctypes.c_void_p): pass +class Image(ctypes.c_void_p): pass +class ChannelStatistics(ctypes.c_void_p): pass +class MagickSizeType(ctypes.c_void_p): pass +class ImageInfo(ctypes.c_void_p): pass +class ExceptionInfo(ctypes.c_void_p): pass +class MagickStatusType(ctypes.c_void_p): pass +class MagickInfo(ctypes.c_void_p): pass +class MagickWand(ctypes.c_void_p): pass + +# MagickSetLastIterator +try: + _magick.MagickSetLastIterator.restype = None + _magick.MagickSetLastIterator.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickSetLastIterator = _magick.MagickSetLastIterator +# MagickSetFirstIterator +try: + _magick.MagickSetFirstIterator.restype = None + _magick.MagickSetFirstIterator.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickSetFirstIterator = _magick.MagickSetFirstIterator +# MagickResetIterator +try: + _magick.MagickResetIterator.restype = None + _magick.MagickResetIterator.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickResetIterator = _magick.MagickResetIterator +# MagickRelinquishMemory +try: + _magick.MagickRelinquishMemory.restype = ctypes.c_void_p + _magick.MagickRelinquishMemory.argtypes = (ctypes.c_void_p,) +except AttributeError,e: + pass +else: + MagickRelinquishMemory = _magick.MagickRelinquishMemory +# MagickWandTerminus +try: + _magick.MagickWandTerminus.restype = None + _magick.MagickWandTerminus.argtypes = () +except AttributeError,e: + pass +else: + MagickWandTerminus = _magick.MagickWandTerminus +# MagickWandGenesis +try: + _magick.MagickWandGenesis.restype = None + _magick.MagickWandGenesis.argtypes = () +except AttributeError,e: + pass +else: + MagickWandGenesis = _magick.MagickWandGenesis +# ClearMagickWand +try: + _magick.ClearMagickWand.restype = None + _magick.ClearMagickWand.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + ClearMagickWand = _magick.ClearMagickWand +# NewMagickWand +try: + _magick.NewMagickWand.restype = MagickWand + _magick.NewMagickWand.argtypes = () +except AttributeError,e: + pass +else: + NewMagickWand = _magick.NewMagickWand +# DestroyMagickWand +try: + _magick.DestroyMagickWand.restype = MagickWand + _magick.DestroyMagickWand.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + DestroyMagickWand = _magick.DestroyMagickWand +# CloneMagickWand +try: + _magick.CloneMagickWand.restype = MagickWand + _magick.CloneMagickWand.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + CloneMagickWand = _magick.CloneMagickWand +# MagickClearException +try: + _magick.MagickClearException.restype = MagickBooleanType + _magick.MagickClearException.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickClearException = _magick.MagickClearException +# IsMagickWand +try: + _magick.IsMagickWand.restype = MagickBooleanType + _magick.IsMagickWand.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + IsMagickWand = _magick.IsMagickWand +# MagickGetException +try: + _magick.MagickGetException.restype = ctypes.POINTER(ctypes.c_char) + _magick.MagickGetException.argtypes = (MagickWand,ctypes.POINTER(ExceptionType)) +except AttributeError,e: + pass +else: + MagickGetException = _magick.MagickGetException +# MagickGetImageVirtualPixelMethod +try: + _magick.MagickGetImageVirtualPixelMethod.restype = VirtualPixelMethod + _magick.MagickGetImageVirtualPixelMethod.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImageVirtualPixelMethod = _magick.MagickGetImageVirtualPixelMethod +# MagickGetNumberImages +try: + _magick.MagickGetNumberImages.restype = ctypes.c_ulong + _magick.MagickGetNumberImages.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetNumberImages = _magick.MagickGetNumberImages +# MagickGetImageWidth +try: + _magick.MagickGetImageWidth.restype = ctypes.c_ulong + _magick.MagickGetImageWidth.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImageWidth = _magick.MagickGetImageWidth +# MagickGetImageTicksPerSecond +try: + _magick.MagickGetImageTicksPerSecond.restype = ctypes.c_ulong + _magick.MagickGetImageTicksPerSecond.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImageTicksPerSecond = _magick.MagickGetImageTicksPerSecond +# MagickGetImageScene +try: + _magick.MagickGetImageScene.restype = ctypes.c_ulong + _magick.MagickGetImageScene.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImageScene = _magick.MagickGetImageScene +# MagickGetImageIterations +try: + _magick.MagickGetImageIterations.restype = ctypes.c_ulong + _magick.MagickGetImageIterations.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImageIterations = _magick.MagickGetImageIterations +# MagickGetImageHeight +try: + _magick.MagickGetImageHeight.restype = ctypes.c_ulong + _magick.MagickGetImageHeight.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImageHeight = _magick.MagickGetImageHeight +# MagickGetImageDepth +try: + _magick.MagickGetImageDepth.restype = ctypes.c_ulong + _magick.MagickGetImageDepth.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImageDepth = _magick.MagickGetImageDepth +# MagickGetImageChannelDepth +try: + _magick.MagickGetImageChannelDepth.restype = ctypes.c_ulong + _magick.MagickGetImageChannelDepth.argtypes = (MagickWand,ChannelType) +except AttributeError,e: + pass +else: + MagickGetImageChannelDepth = _magick.MagickGetImageChannelDepth +# MagickGetImageDelay +try: + _magick.MagickGetImageDelay.restype = ctypes.c_ulong + _magick.MagickGetImageDelay.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImageDelay = _magick.MagickGetImageDelay +# MagickGetImageCompressionQuality +try: + _magick.MagickGetImageCompressionQuality.restype = ctypes.c_ulong + _magick.MagickGetImageCompressionQuality.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImageCompressionQuality = _magick.MagickGetImageCompressionQuality +# MagickGetImageColors +try: + _magick.MagickGetImageColors.restype = ctypes.c_ulong + _magick.MagickGetImageColors.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImageColors = _magick.MagickGetImageColors +# MagickGetImagesBlob +try: + _magick.MagickGetImagesBlob.restype = ctypes.POINTER(ctypes.c_ubyte) + _magick.MagickGetImagesBlob.argtypes = (MagickWand,size_t) +except AttributeError,e: + pass +else: + MagickGetImagesBlob = _magick.MagickGetImagesBlob +# MagickGetImageBlob +try: + _magick.MagickGetImageBlob.restype = ctypes.POINTER(ctypes.c_ubyte) + _magick.MagickGetImageBlob.argtypes = (MagickWand,size_t) +except AttributeError,e: + pass +else: + MagickGetImageBlob = _magick.MagickGetImageBlob +# MagickGetImageUnits +try: + _magick.MagickGetImageUnits.restype = ResolutionType + _magick.MagickGetImageUnits.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImageUnits = _magick.MagickGetImageUnits +# MagickGetImageRenderingIntent +try: + _magick.MagickGetImageRenderingIntent.restype = RenderingIntent + _magick.MagickGetImageRenderingIntent.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImageRenderingIntent = _magick.MagickGetImageRenderingIntent +# MagickGetImageHistogram +try: + _magick.MagickGetImageHistogram.restype = ctypes.POINTER(PixelWand) + _magick.MagickGetImageHistogram.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_ulong)) +except AttributeError,e: + pass +else: + MagickGetImageHistogram = _magick.MagickGetImageHistogram +# NewMagickWandFromImage +try: + _magick.NewMagickWandFromImage.restype = MagickWand + _magick.NewMagickWandFromImage.argtypes = (Image,) +except AttributeError,e: + pass +else: + NewMagickWandFromImage = _magick.NewMagickWandFromImage +# MagickTransformImage +try: + _magick.MagickTransformImage.restype = MagickWand + _magick.MagickTransformImage.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char),ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickTransformImage = _magick.MagickTransformImage +# MagickTextureImage +try: + _magick.MagickTextureImage.restype = MagickWand + _magick.MagickTextureImage.argtypes = (MagickWand,MagickWand) +except AttributeError,e: + pass +else: + MagickTextureImage = _magick.MagickTextureImage +# MagickStereoImage +try: + _magick.MagickStereoImage.restype = MagickWand + _magick.MagickStereoImage.argtypes = (MagickWand,MagickWand) +except AttributeError,e: + pass +else: + MagickStereoImage = _magick.MagickStereoImage +# MagickSteganoImage +try: + _magick.MagickSteganoImage.restype = MagickWand + _magick.MagickSteganoImage.argtypes = (MagickWand,MagickWand,ctypes.c_long) +except AttributeError,e: + pass +else: + MagickSteganoImage = _magick.MagickSteganoImage +# MagickPreviewImages +try: + _magick.MagickPreviewImages.restype = MagickWand + _magick.MagickPreviewImages.argtypes = (MagickWand,PreviewType) +except AttributeError,e: + pass +else: + MagickPreviewImages = _magick.MagickPreviewImages +# MagickMontageImage +try: + _magick.MagickMontageImage.restype = MagickWand + _magick.MagickMontageImage.argtypes = (MagickWand,DrawingWand,ctypes.POINTER(ctypes.c_char),ctypes.POINTER(ctypes.c_char),MontageMode,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickMontageImage = _magick.MagickMontageImage +# MagickMorphImages +try: + _magick.MagickMorphImages.restype = MagickWand + _magick.MagickMorphImages.argtypes = (MagickWand,ctypes.c_ulong) +except AttributeError,e: + pass +else: + MagickMorphImages = _magick.MagickMorphImages +# MagickGetImageRegion +try: + _magick.MagickGetImageRegion.restype = MagickWand + _magick.MagickGetImageRegion.argtypes = (MagickWand,ctypes.c_ulong,ctypes.c_ulong,ctypes.c_long,ctypes.c_long) +except AttributeError,e: + pass +else: + MagickGetImageRegion = _magick.MagickGetImageRegion +# MagickGetImage +try: + _magick.MagickGetImage.restype = MagickWand + _magick.MagickGetImage.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImage = _magick.MagickGetImage +# MagickFxImageChannel +try: + _magick.MagickFxImageChannel.restype = MagickWand + _magick.MagickFxImageChannel.argtypes = (MagickWand,ChannelType,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickFxImageChannel = _magick.MagickFxImageChannel +# MagickFxImage +try: + _magick.MagickFxImage.restype = MagickWand + _magick.MagickFxImage.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickFxImage = _magick.MagickFxImage +# MagickDeconstructImages +try: + _magick.MagickDeconstructImages.restype = MagickWand + _magick.MagickDeconstructImages.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickDeconstructImages = _magick.MagickDeconstructImages +# MagickCompareImageLayers +try: + _magick.MagickCompareImageLayers.restype = MagickWand + _magick.MagickCompareImageLayers.argtypes = (MagickWand,ImageLayerMethod) +except AttributeError,e: + pass +else: + MagickCompareImageLayers = _magick.MagickCompareImageLayers +# MagickCompareImages +try: + _magick.MagickCompareImages.restype = MagickWand + _magick.MagickCompareImages.argtypes = (MagickWand,MagickWand,MetricType,ctypes.POINTER(ctypes.c_double)) +except AttributeError,e: + pass +else: + MagickCompareImages = _magick.MagickCompareImages +# MagickCompareImageChannels +try: + _magick.MagickCompareImageChannels.restype = MagickWand + _magick.MagickCompareImageChannels.argtypes = (MagickWand,MagickWand,ChannelType,MetricType,ctypes.POINTER(ctypes.c_double)) +except AttributeError,e: + pass +else: + MagickCompareImageChannels = _magick.MagickCompareImageChannels +# MagickCombineImages +try: + _magick.MagickCombineImages.restype = MagickWand + _magick.MagickCombineImages.argtypes = (MagickWand,ChannelType) +except AttributeError,e: + pass +else: + MagickCombineImages = _magick.MagickCombineImages +# MagickCoalesceImages +try: + _magick.MagickCoalesceImages.restype = MagickWand + _magick.MagickCoalesceImages.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickCoalesceImages = _magick.MagickCoalesceImages +# MagickAverageImages +try: + _magick.MagickAverageImages.restype = MagickWand + _magick.MagickAverageImages.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickAverageImages = _magick.MagickAverageImages +# MagickAppendImages +try: + _magick.MagickAppendImages.restype = MagickWand + _magick.MagickAppendImages.argtypes = (MagickWand,MagickBooleanType) +except AttributeError,e: + pass +else: + MagickAppendImages = _magick.MagickAppendImages +# MagickWriteImagesFile +try: + _magick.MagickWriteImagesFile.restype = MagickBooleanType + _magick.MagickWriteImagesFile.argtypes = (MagickWand,FILE) +except AttributeError,e: + pass +else: + MagickWriteImagesFile = _magick.MagickWriteImagesFile +# MagickWriteImages +try: + _magick.MagickWriteImages.restype = MagickBooleanType + _magick.MagickWriteImages.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char),MagickBooleanType) +except AttributeError,e: + pass +else: + MagickWriteImages = _magick.MagickWriteImages +# MagickWriteImageFile +try: + _magick.MagickWriteImageFile.restype = MagickBooleanType + _magick.MagickWriteImageFile.argtypes = (MagickWand,FILE) +except AttributeError,e: + pass +else: + MagickWriteImageFile = _magick.MagickWriteImageFile +# MagickWriteImage +try: + _magick.MagickWriteImage.restype = MagickBooleanType + _magick.MagickWriteImage.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickWriteImage = _magick.MagickWriteImage +# MagickWhiteThresholdImage +try: + _magick.MagickWhiteThresholdImage.restype = MagickBooleanType + _magick.MagickWhiteThresholdImage.argtypes = (MagickWand,PixelWand) +except AttributeError,e: + pass +else: + MagickWhiteThresholdImage = _magick.MagickWhiteThresholdImage +# MagickWaveImage +try: + _magick.MagickWaveImage.restype = MagickBooleanType + _magick.MagickWaveImage.argtypes = (MagickWand,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickWaveImage = _magick.MagickWaveImage +# MagickUnsharpMaskImageChannel +try: + _magick.MagickUnsharpMaskImageChannel.restype = MagickBooleanType + _magick.MagickUnsharpMaskImageChannel.argtypes = (MagickWand,ChannelType,ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickUnsharpMaskImageChannel = _magick.MagickUnsharpMaskImageChannel +# MagickUnsharpMaskImage +try: + _magick.MagickUnsharpMaskImage.restype = MagickBooleanType + _magick.MagickUnsharpMaskImage.argtypes = (MagickWand,ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickUnsharpMaskImage = _magick.MagickUnsharpMaskImage +# MagickTrimImage +try: + _magick.MagickTrimImage.restype = MagickBooleanType + _magick.MagickTrimImage.argtypes = (MagickWand,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickTrimImage = _magick.MagickTrimImage +# MagickThumbnailImage +try: + _magick.MagickThumbnailImage.restype = MagickBooleanType + _magick.MagickThumbnailImage.argtypes = (MagickWand,ctypes.c_ulong,ctypes.c_ulong) +except AttributeError,e: + pass +else: + MagickThumbnailImage = _magick.MagickThumbnailImage +# MagickThresholdImageChannel +try: + _magick.MagickThresholdImageChannel.restype = MagickBooleanType + _magick.MagickThresholdImageChannel.argtypes = (MagickWand,ChannelType,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickThresholdImageChannel = _magick.MagickThresholdImageChannel +# MagickThresholdImage +try: + _magick.MagickThresholdImage.restype = MagickBooleanType + _magick.MagickThresholdImage.argtypes = (MagickWand,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickThresholdImage = _magick.MagickThresholdImage +# MagickTintImage +try: + _magick.MagickTintImage.restype = MagickBooleanType + _magick.MagickTintImage.argtypes = (MagickWand,PixelWand,PixelWand) +except AttributeError,e: + pass +else: + MagickTintImage = _magick.MagickTintImage +# MagickSwirlImage +try: + _magick.MagickSwirlImage.restype = MagickBooleanType + _magick.MagickSwirlImage.argtypes = (MagickWand,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickSwirlImage = _magick.MagickSwirlImage +# MagickStripImage +try: + _magick.MagickStripImage.restype = MagickBooleanType + _magick.MagickStripImage.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickStripImage = _magick.MagickStripImage +# MagickSpreadImage +try: + _magick.MagickSpreadImage.restype = MagickBooleanType + _magick.MagickSpreadImage.argtypes = (MagickWand,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickSpreadImage = _magick.MagickSpreadImage +# MagickSpliceImage +try: + _magick.MagickSpliceImage.restype = MagickBooleanType + _magick.MagickSpliceImage.argtypes = (MagickWand,ctypes.c_ulong,ctypes.c_ulong,ctypes.c_long,ctypes.c_long) +except AttributeError,e: + pass +else: + MagickSpliceImage = _magick.MagickSpliceImage +# MagickSolarizeImage +try: + _magick.MagickSolarizeImage.restype = MagickBooleanType + _magick.MagickSolarizeImage.argtypes = (MagickWand,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickSolarizeImage = _magick.MagickSolarizeImage +# MagickSigmoidalContrastImageChannel +try: + _magick.MagickSigmoidalContrastImageChannel.restype = MagickBooleanType + _magick.MagickSigmoidalContrastImageChannel.argtypes = (MagickWand,ChannelType,MagickBooleanType,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickSigmoidalContrastImageChannel = _magick.MagickSigmoidalContrastImageChannel +# MagickSigmoidalContrastImage +try: + _magick.MagickSigmoidalContrastImage.restype = MagickBooleanType + _magick.MagickSigmoidalContrastImage.argtypes = (MagickWand,MagickBooleanType,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickSigmoidalContrastImage = _magick.MagickSigmoidalContrastImage +# MagickShearImage +try: + _magick.MagickShearImage.restype = MagickBooleanType + _magick.MagickShearImage.argtypes = (MagickWand,PixelWand,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickShearImage = _magick.MagickShearImage +# MagickShaveImage +try: + _magick.MagickShaveImage.restype = MagickBooleanType + _magick.MagickShaveImage.argtypes = (MagickWand,ctypes.c_ulong,ctypes.c_ulong) +except AttributeError,e: + pass +else: + MagickShaveImage = _magick.MagickShaveImage +# MagickSharpenImageChannel +try: + _magick.MagickSharpenImageChannel.restype = MagickBooleanType + _magick.MagickSharpenImageChannel.argtypes = (MagickWand,ChannelType,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickSharpenImageChannel = _magick.MagickSharpenImageChannel +# MagickSharpenImage +try: + _magick.MagickSharpenImage.restype = MagickBooleanType + _magick.MagickSharpenImage.argtypes = (MagickWand,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickSharpenImage = _magick.MagickSharpenImage +# MagickShadowImage +try: + _magick.MagickShadowImage.restype = MagickBooleanType + _magick.MagickShadowImage.argtypes = (MagickWand,ctypes.c_double,ctypes.c_double,ctypes.c_long,ctypes.c_long) +except AttributeError,e: + pass +else: + MagickShadowImage = _magick.MagickShadowImage +# MagickSetImageWhitePoint +try: + _magick.MagickSetImageWhitePoint.restype = MagickBooleanType + _magick.MagickSetImageWhitePoint.argtypes = (MagickWand,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickSetImageWhitePoint = _magick.MagickSetImageWhitePoint +# MagickSetImageUnits +try: + _magick.MagickSetImageUnits.restype = MagickBooleanType + _magick.MagickSetImageUnits.argtypes = (MagickWand,ResolutionType) +except AttributeError,e: + pass +else: + MagickSetImageUnits = _magick.MagickSetImageUnits +# MagickSetImageType +try: + _magick.MagickSetImageType.restype = MagickBooleanType + _magick.MagickSetImageType.argtypes = (MagickWand,ImageType) +except AttributeError,e: + pass +else: + MagickSetImageType = _magick.MagickSetImageType +# MagickSetImageTicksPerSecond +try: + _magick.MagickSetImageTicksPerSecond.restype = MagickBooleanType + _magick.MagickSetImageTicksPerSecond.argtypes = (MagickWand,ctypes.c_long) +except AttributeError,e: + pass +else: + MagickSetImageTicksPerSecond = _magick.MagickSetImageTicksPerSecond +# MagickSetImageScene +try: + _magick.MagickSetImageScene.restype = MagickBooleanType + _magick.MagickSetImageScene.argtypes = (MagickWand,ctypes.c_ulong) +except AttributeError,e: + pass +else: + MagickSetImageScene = _magick.MagickSetImageScene +# MagickSetImageResolution +try: + _magick.MagickSetImageResolution.restype = MagickBooleanType + _magick.MagickSetImageResolution.argtypes = (MagickWand,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickSetImageResolution = _magick.MagickSetImageResolution +# MagickSetImageRenderingIntent +try: + _magick.MagickSetImageRenderingIntent.restype = MagickBooleanType + _magick.MagickSetImageRenderingIntent.argtypes = (MagickWand,RenderingIntent) +except AttributeError,e: + pass +else: + MagickSetImageRenderingIntent = _magick.MagickSetImageRenderingIntent +# MagickSetImageRedPrimary +try: + _magick.MagickSetImageRedPrimary.restype = MagickBooleanType + _magick.MagickSetImageRedPrimary.argtypes = (MagickWand,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickSetImageRedPrimary = _magick.MagickSetImageRedPrimary +# MagickSetImagePixels +try: + _magick.MagickSetImagePixels.restype = MagickBooleanType + _magick.MagickSetImagePixels.argtypes = (MagickWand,ctypes.c_long,ctypes.c_long,ctypes.c_ulong,ctypes.c_ulong,ctypes.POINTER(ctypes.c_char),StorageType,ctypes.c_void_p) +except AttributeError,e: + pass +else: + MagickSetImagePixels = _magick.MagickSetImagePixels +# MagickSetImagePage +try: + _magick.MagickSetImagePage.restype = MagickBooleanType + _magick.MagickSetImagePage.argtypes = (MagickWand,ctypes.c_ulong,ctypes.c_ulong,ctypes.c_long,ctypes.c_long) +except AttributeError,e: + pass +else: + MagickSetImagePage = _magick.MagickSetImagePage +# MagickSetImageMatteColor +try: + _magick.MagickSetImageMatteColor.restype = MagickBooleanType + _magick.MagickSetImageMatteColor.argtypes = (MagickWand,PixelWand) +except AttributeError,e: + pass +else: + MagickSetImageMatteColor = _magick.MagickSetImageMatteColor +# MagickSetImageIterations +try: + _magick.MagickSetImageIterations.restype = MagickBooleanType + _magick.MagickSetImageIterations.argtypes = (MagickWand,ctypes.c_ulong) +except AttributeError,e: + pass +else: + MagickSetImageIterations = _magick.MagickSetImageIterations +# MagickSetImageInterlaceScheme +try: + _magick.MagickSetImageInterlaceScheme.restype = MagickBooleanType + _magick.MagickSetImageInterlaceScheme.argtypes = (MagickWand,InterlaceType) +except AttributeError,e: + pass +else: + MagickSetImageInterlaceScheme = _magick.MagickSetImageInterlaceScheme +# MagickSetImageFormat +try: + _magick.MagickSetImageFormat.restype = MagickBooleanType + _magick.MagickSetImageFormat.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickSetImageFormat = _magick.MagickSetImageFormat +# MagickSetImageFilename +try: + _magick.MagickSetImageFilename.restype = MagickBooleanType + _magick.MagickSetImageFilename.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickSetImageFilename = _magick.MagickSetImageFilename +# MagickSetImageExtent +try: + _magick.MagickSetImageExtent.restype = MagickBooleanType + _magick.MagickSetImageExtent.argtypes = (MagickWand,ctypes.c_ulong,ctypes.c_ulong) +except AttributeError,e: + pass +else: + MagickSetImageExtent = _magick.MagickSetImageExtent +# MagickSetImageGamma +try: + _magick.MagickSetImageGamma.restype = MagickBooleanType + _magick.MagickSetImageGamma.argtypes = (MagickWand,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickSetImageGamma = _magick.MagickSetImageGamma +# MagickSetImageGreenPrimary +try: + _magick.MagickSetImageGreenPrimary.restype = MagickBooleanType + _magick.MagickSetImageGreenPrimary.argtypes = (MagickWand,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickSetImageGreenPrimary = _magick.MagickSetImageGreenPrimary +# MagickSetImageCompressionQuality +try: + _magick.MagickSetImageCompressionQuality.restype = MagickBooleanType + _magick.MagickSetImageCompressionQuality.argtypes = (MagickWand,ctypes.c_ulong) +except AttributeError,e: + pass +else: + MagickSetImageCompressionQuality = _magick.MagickSetImageCompressionQuality +# MagickSetImageColorspace +try: + _magick.MagickSetImageColorspace.restype = MagickBooleanType + _magick.MagickSetImageColorspace.argtypes = (MagickWand,ColorspaceType) +except AttributeError,e: + pass +else: + MagickSetImageColorspace = _magick.MagickSetImageColorspace +# MagickSetImageDispose +try: + _magick.MagickSetImageDispose.restype = MagickBooleanType + _magick.MagickSetImageDispose.argtypes = (MagickWand,DisposeType) +except AttributeError,e: + pass +else: + MagickSetImageDispose = _magick.MagickSetImageDispose +# MagickSetImageDepth +try: + _magick.MagickSetImageDepth.restype = MagickBooleanType + _magick.MagickSetImageDepth.argtypes = (MagickWand,ctypes.c_ulong) +except AttributeError,e: + pass +else: + MagickSetImageDepth = _magick.MagickSetImageDepth +# MagickSetImageDelay +try: + _magick.MagickSetImageDelay.restype = MagickBooleanType + _magick.MagickSetImageDelay.argtypes = (MagickWand,ctypes.c_ulong) +except AttributeError,e: + pass +else: + MagickSetImageDelay = _magick.MagickSetImageDelay +# MagickSetImageCompression +try: + _magick.MagickSetImageCompression.restype = MagickBooleanType + _magick.MagickSetImageCompression.argtypes = (MagickWand,CompressionType) +except AttributeError,e: + pass +else: + MagickSetImageCompression = _magick.MagickSetImageCompression +# MagickSetImageCompose +try: + _magick.MagickSetImageCompose.restype = MagickBooleanType + _magick.MagickSetImageCompose.argtypes = (MagickWand,CompositeOperator) +except AttributeError,e: + pass +else: + MagickSetImageCompose = _magick.MagickSetImageCompose +# MagickSetImageColormapColor +try: + _magick.MagickSetImageColormapColor.restype = MagickBooleanType + _magick.MagickSetImageColormapColor.argtypes = (MagickWand,ctypes.c_ulong,PixelWand) +except AttributeError,e: + pass +else: + MagickSetImageColormapColor = _magick.MagickSetImageColormapColor +# MagickSetImageChannelDepth +try: + _magick.MagickSetImageChannelDepth.restype = MagickBooleanType + _magick.MagickSetImageChannelDepth.argtypes = (MagickWand,ChannelType,ctypes.c_ulong) +except AttributeError,e: + pass +else: + MagickSetImageChannelDepth = _magick.MagickSetImageChannelDepth +# MagickSetImageBorderColor +try: + _magick.MagickSetImageBorderColor.restype = MagickBooleanType + _magick.MagickSetImageBorderColor.argtypes = (MagickWand,PixelWand) +except AttributeError,e: + pass +else: + MagickSetImageBorderColor = _magick.MagickSetImageBorderColor +# MagickSetImageBluePrimary +try: + _magick.MagickSetImageBluePrimary.restype = MagickBooleanType + _magick.MagickSetImageBluePrimary.argtypes = (MagickWand,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickSetImageBluePrimary = _magick.MagickSetImageBluePrimary +# MagickSetImageBias +try: + _magick.MagickSetImageBias.restype = MagickBooleanType + _magick.MagickSetImageBias.argtypes = (MagickWand,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickSetImageBias = _magick.MagickSetImageBias +# MagickSetImageBackgroundColor +try: + _magick.MagickSetImageBackgroundColor.restype = MagickBooleanType + _magick.MagickSetImageBackgroundColor.argtypes = (MagickWand,PixelWand) +except AttributeError,e: + pass +else: + MagickSetImageBackgroundColor = _magick.MagickSetImageBackgroundColor +# MagickSetImage +try: + _magick.MagickSetImage.restype = MagickBooleanType + _magick.MagickSetImage.argtypes = (MagickWand,MagickWand) +except AttributeError,e: + pass +else: + MagickSetImage = _magick.MagickSetImage +# MagickSepiaToneImage +try: + _magick.MagickSepiaToneImage.restype = MagickBooleanType + _magick.MagickSepiaToneImage.argtypes = (MagickWand,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickSepiaToneImage = _magick.MagickSepiaToneImage +# MagickSeparateImageChannel +try: + _magick.MagickSeparateImageChannel.restype = MagickBooleanType + _magick.MagickSeparateImageChannel.argtypes = (MagickWand,ChannelType) +except AttributeError,e: + pass +else: + MagickSeparateImageChannel = _magick.MagickSeparateImageChannel +# MagickScaleImage +try: + _magick.MagickScaleImage.restype = MagickBooleanType + _magick.MagickScaleImage.argtypes = (MagickWand,ctypes.c_ulong,ctypes.c_ulong) +except AttributeError,e: + pass +else: + MagickScaleImage = _magick.MagickScaleImage +# MagickSampleImage +try: + _magick.MagickSampleImage.restype = MagickBooleanType + _magick.MagickSampleImage.argtypes = (MagickWand,ctypes.c_ulong,ctypes.c_ulong) +except AttributeError,e: + pass +else: + MagickSampleImage = _magick.MagickSampleImage +# MagickRotateImage +try: + _magick.MagickRotateImage.restype = MagickBooleanType + _magick.MagickRotateImage.argtypes = (MagickWand,PixelWand,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickRotateImage = _magick.MagickRotateImage +# MagickRollImage +try: + _magick.MagickRollImage.restype = MagickBooleanType + _magick.MagickRollImage.argtypes = (MagickWand,ctypes.c_long,ctypes.c_long) +except AttributeError,e: + pass +else: + MagickRollImage = _magick.MagickRollImage +# MagickResizeImage +try: + _magick.MagickResizeImage.restype = MagickBooleanType + _magick.MagickResizeImage.argtypes = (MagickWand,ctypes.c_ulong,ctypes.c_ulong,FilterTypes,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickResizeImage = _magick.MagickResizeImage +# MagickResampleImage +try: + _magick.MagickResampleImage.restype = MagickBooleanType + _magick.MagickResampleImage.argtypes = (MagickWand,ctypes.c_double,ctypes.c_double,FilterTypes,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickResampleImage = _magick.MagickResampleImage +# MagickRemoveImage +try: + _magick.MagickRemoveImage.restype = MagickBooleanType + _magick.MagickRemoveImage.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickRemoveImage = _magick.MagickRemoveImage +# MagickReduceNoiseImage +try: + _magick.MagickReduceNoiseImage.restype = MagickBooleanType + _magick.MagickReduceNoiseImage.argtypes = (MagickWand,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickReduceNoiseImage = _magick.MagickReduceNoiseImage +# MagickReadImageFile +try: + _magick.MagickReadImageFile.restype = MagickBooleanType + _magick.MagickReadImageFile.argtypes = (MagickWand,FILE) +except AttributeError,e: + pass +else: + MagickReadImageFile = _magick.MagickReadImageFile +# MagickReadImageBlob +try: + _magick.MagickReadImageBlob.restype = MagickBooleanType + _magick.MagickReadImageBlob.argtypes = (MagickWand,ctypes.c_void_p,ctypes.c_ulong) +except AttributeError,e: + pass +else: + MagickReadImageBlob = _magick.MagickReadImageBlob +# MagickReadImage +try: + _magick.MagickReadImage.restype = MagickBooleanType + _magick.MagickReadImage.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickReadImage = _magick.MagickReadImage +# MagickRaiseImage +try: + _magick.MagickRaiseImage.restype = MagickBooleanType + _magick.MagickRaiseImage.argtypes = (MagickWand,ctypes.c_ulong,ctypes.c_ulong,ctypes.c_long,ctypes.c_long,MagickBooleanType) +except AttributeError,e: + pass +else: + MagickRaiseImage = _magick.MagickRaiseImage +# MagickRadialBlurImageChannel +try: + _magick.MagickRadialBlurImageChannel.restype = MagickBooleanType + _magick.MagickRadialBlurImageChannel.argtypes = (MagickWand,ChannelType,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickRadialBlurImageChannel = _magick.MagickRadialBlurImageChannel +# MagickRadialBlurImage +try: + _magick.MagickRadialBlurImage.restype = MagickBooleanType + _magick.MagickRadialBlurImage.argtypes = (MagickWand,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickRadialBlurImage = _magick.MagickRadialBlurImage +# MagickQuantizeImages +try: + _magick.MagickQuantizeImages.restype = MagickBooleanType + _magick.MagickQuantizeImages.argtypes = (MagickWand,ctypes.c_ulong,ColorspaceType,ctypes.c_ulong,MagickBooleanType,MagickBooleanType) +except AttributeError,e: + pass +else: + MagickQuantizeImages = _magick.MagickQuantizeImages +# MagickQuantizeImage +try: + _magick.MagickQuantizeImage.restype = MagickBooleanType + _magick.MagickQuantizeImage.argtypes = (MagickWand,ctypes.c_ulong,ColorspaceType,ctypes.c_ulong,MagickBooleanType,MagickBooleanType) +except AttributeError,e: + pass +else: + MagickQuantizeImage = _magick.MagickQuantizeImage +# MagickPreviousImage +try: + _magick.MagickPreviousImage.restype = MagickBooleanType + _magick.MagickPreviousImage.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickPreviousImage = _magick.MagickPreviousImage +# MagickPosterizeImage +try: + _magick.MagickPosterizeImage.restype = MagickBooleanType + _magick.MagickPosterizeImage.argtypes = (MagickWand,ctypes.c_ulong,MagickBooleanType) +except AttributeError,e: + pass +else: + MagickPosterizeImage = _magick.MagickPosterizeImage +# MagickPaintTransparentImage +try: + _magick.MagickPaintTransparentImage.restype = MagickBooleanType + _magick.MagickPaintTransparentImage.argtypes = (MagickWand,PixelWand,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickPaintTransparentImage = _magick.MagickPaintTransparentImage +# MagickPaintFloodfillImage +try: + _magick.MagickPaintFloodfillImage.restype = MagickBooleanType + _magick.MagickPaintFloodfillImage.argtypes = (MagickWand,ChannelType,PixelWand,ctypes.c_double,PixelWand,ctypes.c_long,ctypes.c_long) +except AttributeError,e: + pass +else: + MagickPaintFloodfillImage = _magick.MagickPaintFloodfillImage +# MagickOrderedPosterizeImageChannel +try: + _magick.MagickOrderedPosterizeImageChannel.restype = MagickBooleanType + _magick.MagickOrderedPosterizeImageChannel.argtypes = (MagickWand,ChannelType,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickOrderedPosterizeImageChannel = _magick.MagickOrderedPosterizeImageChannel +# MagickOrderedPosterizeImage +try: + _magick.MagickOrderedPosterizeImage.restype = MagickBooleanType + _magick.MagickOrderedPosterizeImage.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickOrderedPosterizeImage = _magick.MagickOrderedPosterizeImage +# MagickOilPaintImage +try: + _magick.MagickOilPaintImage.restype = MagickBooleanType + _magick.MagickOilPaintImage.argtypes = (MagickWand,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickOilPaintImage = _magick.MagickOilPaintImage +# MagickNormalizeImageChannel +try: + _magick.MagickNormalizeImageChannel.restype = MagickBooleanType + _magick.MagickNormalizeImageChannel.argtypes = (MagickWand,ChannelType) +except AttributeError,e: + pass +else: + MagickNormalizeImageChannel = _magick.MagickNormalizeImageChannel +# MagickNormalizeImage +try: + _magick.MagickNormalizeImage.restype = MagickBooleanType + _magick.MagickNormalizeImage.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickNormalizeImage = _magick.MagickNormalizeImage +# MagickNextImage +try: + _magick.MagickNextImage.restype = MagickBooleanType + _magick.MagickNextImage.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickNextImage = _magick.MagickNextImage +# MagickNewImage +try: + _magick.MagickNewImage.restype = MagickBooleanType + _magick.MagickNewImage.argtypes = (MagickWand,ctypes.c_ulong,ctypes.c_ulong,PixelWand) +except AttributeError,e: + pass +else: + MagickNewImage = _magick.MagickNewImage +# MagickNegateImageChannel +try: + _magick.MagickNegateImageChannel.restype = MagickBooleanType + _magick.MagickNegateImageChannel.argtypes = (MagickWand,ChannelType,MagickBooleanType) +except AttributeError,e: + pass +else: + MagickNegateImageChannel = _magick.MagickNegateImageChannel +# MagickNegateImage +try: + _magick.MagickNegateImage.restype = MagickBooleanType + _magick.MagickNegateImage.argtypes = (MagickWand,MagickBooleanType) +except AttributeError,e: + pass +else: + MagickNegateImage = _magick.MagickNegateImage +# MagickMotionBlurImage +try: + _magick.MagickMotionBlurImage.restype = MagickBooleanType + _magick.MagickMotionBlurImage.argtypes = (MagickWand,ctypes.c_double,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickMotionBlurImage = _magick.MagickMotionBlurImage +# MagickModulateImage +try: + _magick.MagickModulateImage.restype = MagickBooleanType + _magick.MagickModulateImage.argtypes = (MagickWand,ctypes.c_double,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickModulateImage = _magick.MagickModulateImage +# MagickMinifyImage +try: + _magick.MagickMinifyImage.restype = MagickBooleanType + _magick.MagickMinifyImage.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickMinifyImage = _magick.MagickMinifyImage +# MagickMedianFilterImage +try: + _magick.MagickMedianFilterImage.restype = MagickBooleanType + _magick.MagickMedianFilterImage.argtypes = (MagickWand,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickMedianFilterImage = _magick.MagickMedianFilterImage +# MagickMapImage +try: + _magick.MagickMapImage.restype = MagickBooleanType + _magick.MagickMapImage.argtypes = (MagickWand,MagickWand,MagickBooleanType) +except AttributeError,e: + pass +else: + MagickMapImage = _magick.MagickMapImage +# MagickMagnifyImage +try: + _magick.MagickMagnifyImage.restype = MagickBooleanType + _magick.MagickMagnifyImage.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickMagnifyImage = _magick.MagickMagnifyImage +# MagickLinearStretchImage +try: + _magick.MagickLinearStretchImage.restype = MagickBooleanType + _magick.MagickLinearStretchImage.argtypes = (MagickWand,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickLinearStretchImage = _magick.MagickLinearStretchImage +# MagickLevelImageChannel +try: + _magick.MagickLevelImageChannel.restype = MagickBooleanType + _magick.MagickLevelImageChannel.argtypes = (MagickWand,ChannelType,ctypes.c_double,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickLevelImageChannel = _magick.MagickLevelImageChannel +# MagickLevelImage +try: + _magick.MagickLevelImage.restype = MagickBooleanType + _magick.MagickLevelImage.argtypes = (MagickWand,ctypes.c_double,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickLevelImage = _magick.MagickLevelImage +# MagickLabelImage +try: + _magick.MagickLabelImage.restype = MagickBooleanType + _magick.MagickLabelImage.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickLabelImage = _magick.MagickLabelImage +# MagickImplodeImage +try: + _magick.MagickImplodeImage.restype = MagickBooleanType + _magick.MagickImplodeImage.argtypes = (MagickWand,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickImplodeImage = _magick.MagickImplodeImage +# MagickHasPreviousImage +try: + _magick.MagickHasPreviousImage.restype = MagickBooleanType + _magick.MagickHasPreviousImage.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickHasPreviousImage = _magick.MagickHasPreviousImage +# MagickHasNextImage +try: + _magick.MagickHasNextImage.restype = MagickBooleanType + _magick.MagickHasNextImage.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickHasNextImage = _magick.MagickHasNextImage +# MagickGetImageWhitePoint +try: + _magick.MagickGetImageWhitePoint.restype = MagickBooleanType + _magick.MagickGetImageWhitePoint.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_double),ctypes.POINTER(ctypes.c_double)) +except AttributeError,e: + pass +else: + MagickGetImageWhitePoint = _magick.MagickGetImageWhitePoint +# MagickGetImageResolution +try: + _magick.MagickGetImageResolution.restype = MagickBooleanType + _magick.MagickGetImageResolution.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_double),ctypes.POINTER(ctypes.c_double)) +except AttributeError,e: + pass +else: + MagickGetImageResolution = _magick.MagickGetImageResolution +# MagickGetImageRedPrimary +try: + _magick.MagickGetImageRedPrimary.restype = MagickBooleanType + _magick.MagickGetImageRedPrimary.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_double),ctypes.POINTER(ctypes.c_double)) +except AttributeError,e: + pass +else: + MagickGetImageRedPrimary = _magick.MagickGetImageRedPrimary +# MagickGetImageRange +try: + _magick.MagickGetImageRange.restype = MagickBooleanType + _magick.MagickGetImageRange.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_double),ctypes.POINTER(ctypes.c_double)) +except AttributeError,e: + pass +else: + MagickGetImageRange = _magick.MagickGetImageRange +# MagickGetImagePixels +try: + _magick.MagickGetImagePixels.restype = MagickBooleanType + _magick.MagickGetImagePixels.argtypes = (MagickWand,ctypes.c_long,ctypes.c_long,ctypes.c_ulong,ctypes.c_ulong,ctypes.POINTER(ctypes.c_char),StorageType,ctypes.c_void_p) +except AttributeError,e: + pass +else: + MagickGetImagePixels = _magick.MagickGetImagePixels +# MagickGetImagePixelColor +try: + _magick.MagickGetImagePixelColor.restype = MagickBooleanType + _magick.MagickGetImagePixelColor.argtypes = (MagickWand,ctypes.c_long,ctypes.c_long,PixelWand) +except AttributeError,e: + pass +else: + MagickGetImagePixelColor = _magick.MagickGetImagePixelColor +# MagickGetImagePage +try: + _magick.MagickGetImagePage.restype = MagickBooleanType + _magick.MagickGetImagePage.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_ulong),ctypes.POINTER(ctypes.c_ulong),ctypes.POINTER(ctypes.c_long),ctypes.POINTER(ctypes.c_long)) +except AttributeError,e: + pass +else: + MagickGetImagePage = _magick.MagickGetImagePage +# MagickGetImageLength +try: + _magick.MagickGetImageLength.restype = MagickBooleanType + _magick.MagickGetImageLength.argtypes = (MagickWand,MagickSizeType) +except AttributeError,e: + pass +else: + MagickGetImageLength = _magick.MagickGetImageLength +# MagickGetImageMatteColor +try: + _magick.MagickGetImageMatteColor.restype = MagickBooleanType + _magick.MagickGetImageMatteColor.argtypes = (MagickWand,PixelWand) +except AttributeError,e: + pass +else: + MagickGetImageMatteColor = _magick.MagickGetImageMatteColor +# MagickGetImageMatte +try: + _magick.MagickGetImageMatte.restype = MagickBooleanType + _magick.MagickGetImageMatte.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImageMatte = _magick.MagickGetImageMatte +# MagickGetImageGreenPrimary +try: + _magick.MagickGetImageGreenPrimary.restype = MagickBooleanType + _magick.MagickGetImageGreenPrimary.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_double),ctypes.POINTER(ctypes.c_double)) +except AttributeError,e: + pass +else: + MagickGetImageGreenPrimary = _magick.MagickGetImageGreenPrimary +# MagickGetImageColormapColor +try: + _magick.MagickGetImageColormapColor.restype = MagickBooleanType + _magick.MagickGetImageColormapColor.argtypes = (MagickWand,ctypes.c_ulong,PixelWand) +except AttributeError,e: + pass +else: + MagickGetImageColormapColor = _magick.MagickGetImageColormapColor +# MagickGetImageChannelRange +try: + _magick.MagickGetImageChannelRange.restype = MagickBooleanType + _magick.MagickGetImageChannelRange.argtypes = (MagickWand,ChannelType,ctypes.POINTER(ctypes.c_double),ctypes.POINTER(ctypes.c_double)) +except AttributeError,e: + pass +else: + MagickGetImageChannelRange = _magick.MagickGetImageChannelRange +# MagickGetImageChannelMean +try: + _magick.MagickGetImageChannelMean.restype = MagickBooleanType + _magick.MagickGetImageChannelMean.argtypes = (MagickWand,ChannelType,ctypes.POINTER(ctypes.c_double),ctypes.POINTER(ctypes.c_double)) +except AttributeError,e: + pass +else: + MagickGetImageChannelMean = _magick.MagickGetImageChannelMean +# MagickGetImageDistortion +try: + _magick.MagickGetImageDistortion.restype = MagickBooleanType + _magick.MagickGetImageDistortion.argtypes = (MagickWand,MagickWand,MetricType,ctypes.POINTER(ctypes.c_double)) +except AttributeError,e: + pass +else: + MagickGetImageDistortion = _magick.MagickGetImageDistortion +# MagickGetImageChannelDistortion +try: + _magick.MagickGetImageChannelDistortion.restype = MagickBooleanType + _magick.MagickGetImageChannelDistortion.argtypes = (MagickWand,MagickWand,ChannelType,MetricType,ctypes.POINTER(ctypes.c_double)) +except AttributeError,e: + pass +else: + MagickGetImageChannelDistortion = _magick.MagickGetImageChannelDistortion +# MagickGetImageBorderColor +try: + _magick.MagickGetImageBorderColor.restype = MagickBooleanType + _magick.MagickGetImageBorderColor.argtypes = (MagickWand,PixelWand) +except AttributeError,e: + pass +else: + MagickGetImageBorderColor = _magick.MagickGetImageBorderColor +# MagickGetImageBluePrimary +try: + _magick.MagickGetImageBluePrimary.restype = MagickBooleanType + _magick.MagickGetImageBluePrimary.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_double),ctypes.POINTER(ctypes.c_double)) +except AttributeError,e: + pass +else: + MagickGetImageBluePrimary = _magick.MagickGetImageBluePrimary +# MagickGetImageBackgroundColor +try: + _magick.MagickGetImageBackgroundColor.restype = MagickBooleanType + _magick.MagickGetImageBackgroundColor.argtypes = (MagickWand,PixelWand) +except AttributeError,e: + pass +else: + MagickGetImageBackgroundColor = _magick.MagickGetImageBackgroundColor +# MagickGaussianBlurImageChannel +try: + _magick.MagickGaussianBlurImageChannel.restype = MagickBooleanType + _magick.MagickGaussianBlurImageChannel.argtypes = (MagickWand,ChannelType,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickGaussianBlurImageChannel = _magick.MagickGaussianBlurImageChannel +# MagickGaussianBlurImage +try: + _magick.MagickGaussianBlurImage.restype = MagickBooleanType + _magick.MagickGaussianBlurImage.argtypes = (MagickWand,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickGaussianBlurImage = _magick.MagickGaussianBlurImage +# MagickGammaImageChannel +try: + _magick.MagickGammaImageChannel.restype = MagickBooleanType + _magick.MagickGammaImageChannel.argtypes = (MagickWand,ChannelType,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickGammaImageChannel = _magick.MagickGammaImageChannel +# MagickGammaImage +try: + _magick.MagickGammaImage.restype = MagickBooleanType + _magick.MagickGammaImage.argtypes = (MagickWand,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickGammaImage = _magick.MagickGammaImage +# MagickFrameImage +try: + _magick.MagickFrameImage.restype = MagickBooleanType + _magick.MagickFrameImage.argtypes = (MagickWand,PixelWand,ctypes.c_ulong,ctypes.c_ulong,ctypes.c_long,ctypes.c_long) +except AttributeError,e: + pass +else: + MagickFrameImage = _magick.MagickFrameImage +# MagickFlopImage +try: + _magick.MagickFlopImage.restype = MagickBooleanType + _magick.MagickFlopImage.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickFlopImage = _magick.MagickFlopImage +# MagickFlipImage +try: + _magick.MagickFlipImage.restype = MagickBooleanType + _magick.MagickFlipImage.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickFlipImage = _magick.MagickFlipImage +# MagickExtentImage +try: + _magick.MagickExtentImage.restype = MagickBooleanType + _magick.MagickExtentImage.argtypes = (MagickWand,ctypes.c_ulong,ctypes.c_ulong,ctypes.c_long,ctypes.c_long) +except AttributeError,e: + pass +else: + MagickExtentImage = _magick.MagickExtentImage +# MagickEvaluateImageChannel +try: + _magick.MagickEvaluateImageChannel.restype = MagickBooleanType + _magick.MagickEvaluateImageChannel.argtypes = (MagickWand,ChannelType,MagickEvaluateOperator,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickEvaluateImageChannel = _magick.MagickEvaluateImageChannel +# MagickEvaluateImage +try: + _magick.MagickEvaluateImage.restype = MagickBooleanType + _magick.MagickEvaluateImage.argtypes = (MagickWand,MagickEvaluateOperator,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickEvaluateImage = _magick.MagickEvaluateImage +# MagickEqualizeImage +try: + _magick.MagickEqualizeImage.restype = MagickBooleanType + _magick.MagickEqualizeImage.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickEqualizeImage = _magick.MagickEqualizeImage +# MagickEnhanceImage +try: + _magick.MagickEnhanceImage.restype = MagickBooleanType + _magick.MagickEnhanceImage.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickEnhanceImage = _magick.MagickEnhanceImage +# MagickEmbossImage +try: + _magick.MagickEmbossImage.restype = MagickBooleanType + _magick.MagickEmbossImage.argtypes = (MagickWand,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickEmbossImage = _magick.MagickEmbossImage +# MagickEdgeImage +try: + _magick.MagickEdgeImage.restype = MagickBooleanType + _magick.MagickEdgeImage.argtypes = (MagickWand,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickEdgeImage = _magick.MagickEdgeImage +# MagickDrawImage +try: + _magick.MagickDrawImage.restype = MagickBooleanType + _magick.MagickDrawImage.argtypes = (MagickWand,DrawingWand) +except AttributeError,e: + pass +else: + MagickDrawImage = _magick.MagickDrawImage +# MagickDistortImage +try: + _magick.MagickDistortImage.restype = MagickBooleanType + _magick.MagickDistortImage.argtypes = (MagickWand,DistortImageMethod,ctypes.c_ulong,ctypes.POINTER(ctypes.c_double),MagickBooleanType) +except AttributeError,e: + pass +else: + MagickDistortImage = _magick.MagickDistortImage +# MagickDisplayImages +try: + _magick.MagickDisplayImages.restype = MagickBooleanType + _magick.MagickDisplayImages.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickDisplayImages = _magick.MagickDisplayImages +# MagickDisplayImage +try: + _magick.MagickDisplayImage.restype = MagickBooleanType + _magick.MagickDisplayImage.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickDisplayImage = _magick.MagickDisplayImage +# MagickDespeckleImage +try: + _magick.MagickDespeckleImage.restype = MagickBooleanType + _magick.MagickDespeckleImage.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickDespeckleImage = _magick.MagickDespeckleImage +# MagickCycleColormapImage +try: + _magick.MagickCycleColormapImage.restype = MagickBooleanType + _magick.MagickCycleColormapImage.argtypes = (MagickWand,ctypes.c_long) +except AttributeError,e: + pass +else: + MagickCycleColormapImage = _magick.MagickCycleColormapImage +# MagickCropImage +try: + _magick.MagickCropImage.restype = MagickBooleanType + _magick.MagickCropImage.argtypes = (MagickWand,ctypes.c_ulong,ctypes.c_ulong,ctypes.c_long,ctypes.c_long) +except AttributeError,e: + pass +else: + MagickCropImage = _magick.MagickCropImage +# MagickConvolveImageChannel +try: + _magick.MagickConvolveImageChannel.restype = MagickBooleanType + _magick.MagickConvolveImageChannel.argtypes = (MagickWand,ChannelType,ctypes.c_ulong,ctypes.POINTER(ctypes.c_double)) +except AttributeError,e: + pass +else: + MagickConvolveImageChannel = _magick.MagickConvolveImageChannel +# MagickConvolveImage +try: + _magick.MagickConvolveImage.restype = MagickBooleanType + _magick.MagickConvolveImage.argtypes = (MagickWand,ctypes.c_ulong,ctypes.POINTER(ctypes.c_double)) +except AttributeError,e: + pass +else: + MagickConvolveImage = _magick.MagickConvolveImage +# MagickContrastStretchImageChannel +try: + _magick.MagickContrastStretchImageChannel.restype = MagickBooleanType + _magick.MagickContrastStretchImageChannel.argtypes = (MagickWand,ChannelType,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickContrastStretchImageChannel = _magick.MagickContrastStretchImageChannel +# MagickContrastStretchImage +try: + _magick.MagickContrastStretchImage.restype = MagickBooleanType + _magick.MagickContrastStretchImage.argtypes = (MagickWand,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickContrastStretchImage = _magick.MagickContrastStretchImage +# MagickContrastImage +try: + _magick.MagickContrastImage.restype = MagickBooleanType + _magick.MagickContrastImage.argtypes = (MagickWand,MagickBooleanType) +except AttributeError,e: + pass +else: + MagickContrastImage = _magick.MagickContrastImage +# MagickConstituteImage +try: + _magick.MagickConstituteImage.restype = MagickBooleanType + _magick.MagickConstituteImage.argtypes = (MagickWand,ctypes.c_ulong,ctypes.c_ulong,ctypes.POINTER(ctypes.c_char),StorageType,ctypes.c_void_p) +except AttributeError,e: + pass +else: + MagickConstituteImage = _magick.MagickConstituteImage +# MagickCompositeImageChannel +try: + _magick.MagickCompositeImageChannel.restype = MagickBooleanType + _magick.MagickCompositeImageChannel.argtypes = (MagickWand,ChannelType,MagickWand,CompositeOperator,ctypes.c_long,ctypes.c_long) +except AttributeError,e: + pass +else: + MagickCompositeImageChannel = _magick.MagickCompositeImageChannel +# MagickCompositeImage +try: + _magick.MagickCompositeImage.restype = MagickBooleanType + _magick.MagickCompositeImage.argtypes = (MagickWand,MagickWand,CompositeOperator,ctypes.c_long,ctypes.c_long) +except AttributeError,e: + pass +else: + MagickCompositeImage = _magick.MagickCompositeImage +# MagickCommentImage +try: + _magick.MagickCommentImage.restype = MagickBooleanType + _magick.MagickCommentImage.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickCommentImage = _magick.MagickCommentImage +# MagickColorizeImage +try: + _magick.MagickColorizeImage.restype = MagickBooleanType + _magick.MagickColorizeImage.argtypes = (MagickWand,PixelWand,PixelWand) +except AttributeError,e: + pass +else: + MagickColorizeImage = _magick.MagickColorizeImage +# MagickClutImageChannel +try: + _magick.MagickClutImageChannel.restype = MagickBooleanType + _magick.MagickClutImageChannel.argtypes = (MagickWand,ChannelType,MagickWand) +except AttributeError,e: + pass +else: + MagickClutImageChannel = _magick.MagickClutImageChannel +# MagickClutImage +try: + _magick.MagickClutImage.restype = MagickBooleanType + _magick.MagickClutImage.argtypes = (MagickWand,MagickWand) +except AttributeError,e: + pass +else: + MagickClutImage = _magick.MagickClutImage +# MagickClipImage +try: + _magick.MagickClipImage.restype = MagickBooleanType + _magick.MagickClipImage.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickClipImage = _magick.MagickClipImage +# MagickChopImage +try: + _magick.MagickChopImage.restype = MagickBooleanType + _magick.MagickChopImage.argtypes = (MagickWand,ctypes.c_ulong,ctypes.c_ulong,ctypes.c_long,ctypes.c_long) +except AttributeError,e: + pass +else: + MagickChopImage = _magick.MagickChopImage +# MagickCharcoalImage +try: + _magick.MagickCharcoalImage.restype = MagickBooleanType + _magick.MagickCharcoalImage.argtypes = (MagickWand,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickCharcoalImage = _magick.MagickCharcoalImage +# MagickBorderImage +try: + _magick.MagickBorderImage.restype = MagickBooleanType + _magick.MagickBorderImage.argtypes = (MagickWand,PixelWand,ctypes.c_ulong,ctypes.c_ulong) +except AttributeError,e: + pass +else: + MagickBorderImage = _magick.MagickBorderImage +# MagickBlurImageChannel +try: + _magick.MagickBlurImageChannel.restype = MagickBooleanType + _magick.MagickBlurImageChannel.argtypes = (MagickWand,ChannelType,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickBlurImageChannel = _magick.MagickBlurImageChannel +# MagickBlurImage +try: + _magick.MagickBlurImage.restype = MagickBooleanType + _magick.MagickBlurImage.argtypes = (MagickWand,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickBlurImage = _magick.MagickBlurImage +# MagickBlackThresholdImage +try: + _magick.MagickBlackThresholdImage.restype = MagickBooleanType + _magick.MagickBlackThresholdImage.argtypes = (MagickWand,PixelWand) +except AttributeError,e: + pass +else: + MagickBlackThresholdImage = _magick.MagickBlackThresholdImage +# MagickAnimateImages +try: + _magick.MagickAnimateImages.restype = MagickBooleanType + _magick.MagickAnimateImages.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickAnimateImages = _magick.MagickAnimateImages +# MagickAnnotateImage +try: + _magick.MagickAnnotateImage.restype = MagickBooleanType + _magick.MagickAnnotateImage.argtypes = (MagickWand,DrawingWand,ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickAnnotateImage = _magick.MagickAnnotateImage +# MagickAffineTransformImage +try: + _magick.MagickAffineTransformImage.restype = MagickBooleanType + _magick.MagickAffineTransformImage.argtypes = (MagickWand,DrawingWand) +except AttributeError,e: + pass +else: + MagickAffineTransformImage = _magick.MagickAffineTransformImage +# MagickAddNoiseImageChannel +try: + _magick.MagickAddNoiseImageChannel.restype = MagickBooleanType + _magick.MagickAddNoiseImageChannel.argtypes = (MagickWand,ChannelType,NoiseType) +except AttributeError,e: + pass +else: + MagickAddNoiseImageChannel = _magick.MagickAddNoiseImageChannel +# MagickAddNoiseImage +try: + _magick.MagickAddNoiseImage.restype = MagickBooleanType + _magick.MagickAddNoiseImage.argtypes = (MagickWand,NoiseType) +except AttributeError,e: + pass +else: + MagickAddNoiseImage = _magick.MagickAddNoiseImage +# MagickAddImage +try: + _magick.MagickAddImage.restype = MagickBooleanType + _magick.MagickAddImage.argtypes = (MagickWand,MagickWand) +except AttributeError,e: + pass +else: + MagickAddImage = _magick.MagickAddImage +# MagickAdaptiveThresholdImage +try: + _magick.MagickAdaptiveThresholdImage.restype = MagickBooleanType + _magick.MagickAdaptiveThresholdImage.argtypes = (MagickWand,ctypes.c_ulong,ctypes.c_ulong,ctypes.c_long) +except AttributeError,e: + pass +else: + MagickAdaptiveThresholdImage = _magick.MagickAdaptiveThresholdImage +# MagickAdaptiveSharpenImageChannel +try: + _magick.MagickAdaptiveSharpenImageChannel.restype = MagickBooleanType + _magick.MagickAdaptiveSharpenImageChannel.argtypes = (MagickWand,ChannelType,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickAdaptiveSharpenImageChannel = _magick.MagickAdaptiveSharpenImageChannel +# MagickAdaptiveSharpenImage +try: + _magick.MagickAdaptiveSharpenImage.restype = MagickBooleanType + _magick.MagickAdaptiveSharpenImage.argtypes = (MagickWand,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickAdaptiveSharpenImage = _magick.MagickAdaptiveSharpenImage +# MagickAdaptiveResizeImage +try: + _magick.MagickAdaptiveResizeImage.restype = MagickBooleanType + _magick.MagickAdaptiveResizeImage.argtypes = (MagickWand,ctypes.c_ulong,ctypes.c_ulong) +except AttributeError,e: + pass +else: + MagickAdaptiveResizeImage = _magick.MagickAdaptiveResizeImage +# MagickAdaptiveBlurImageChannel +try: + _magick.MagickAdaptiveBlurImageChannel.restype = MagickBooleanType + _magick.MagickAdaptiveBlurImageChannel.argtypes = (MagickWand,ChannelType,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickAdaptiveBlurImageChannel = _magick.MagickAdaptiveBlurImageChannel +# MagickAdaptiveBlurImage +try: + _magick.MagickAdaptiveBlurImage.restype = MagickBooleanType + _magick.MagickAdaptiveBlurImage.argtypes = (MagickWand,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickAdaptiveBlurImage = _magick.MagickAdaptiveBlurImage +# MagickGetImageInterpolateMethod +try: + _magick.MagickGetImageInterpolateMethod.restype = InterpolatePixelMethod + _magick.MagickGetImageInterpolateMethod.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImageInterpolateMethod = _magick.MagickGetImageInterpolateMethod +# MagickGetImageInterlaceScheme +try: + _magick.MagickGetImageInterlaceScheme.restype = InterlaceType + _magick.MagickGetImageInterlaceScheme.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImageInterlaceScheme = _magick.MagickGetImageInterlaceScheme +# MagickGetImageType +try: + _magick.MagickGetImageType.restype = ImageType + _magick.MagickGetImageType.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImageType = _magick.MagickGetImageType +# GetImageFromMagickWand +try: + _magick.GetImageFromMagickWand.restype = Image + _magick.GetImageFromMagickWand.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + GetImageFromMagickWand = _magick.GetImageFromMagickWand +# MagickDestroyImage +try: + _magick.MagickDestroyImage.restype = Image + _magick.MagickDestroyImage.argtypes = (Image,) +except AttributeError,e: + pass +else: + MagickDestroyImage = _magick.MagickDestroyImage +# MagickGetImageTotalInkDensity +try: + _magick.MagickGetImageTotalInkDensity.restype = ctypes.c_double + _magick.MagickGetImageTotalInkDensity.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImageTotalInkDensity = _magick.MagickGetImageTotalInkDensity +# MagickGetImageGamma +try: + _magick.MagickGetImageGamma.restype = ctypes.c_double + _magick.MagickGetImageGamma.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImageGamma = _magick.MagickGetImageGamma +# MagickGetImageDispose +try: + _magick.MagickGetImageDispose.restype = DisposeType + _magick.MagickGetImageDispose.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImageDispose = _magick.MagickGetImageDispose +# MagickGetImageCompression +try: + _magick.MagickGetImageCompression.restype = CompressionType + _magick.MagickGetImageCompression.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImageCompression = _magick.MagickGetImageCompression +# MagickGetImageColorspace +try: + _magick.MagickGetImageColorspace.restype = ColorspaceType + _magick.MagickGetImageColorspace.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImageColorspace = _magick.MagickGetImageColorspace +# MagickGetImageCompose +try: + _magick.MagickGetImageCompose.restype = CompositeOperator + _magick.MagickGetImageCompose.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImageCompose = _magick.MagickGetImageCompose +# MagickIdentifyImage +try: + _magick.MagickIdentifyImage.restype = ctypes.POINTER(ctypes.c_char) + _magick.MagickIdentifyImage.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickIdentifyImage = _magick.MagickIdentifyImage +# MagickGetImageSignature +try: + _magick.MagickGetImageSignature.restype = ctypes.POINTER(ctypes.c_char) + _magick.MagickGetImageSignature.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImageSignature = _magick.MagickGetImageSignature +# MagickGetImageFormat +try: + _magick.MagickGetImageFormat.restype = ctypes.POINTER(ctypes.c_char) + _magick.MagickGetImageFormat.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImageFormat = _magick.MagickGetImageFormat +# MagickGetImageFilename +try: + _magick.MagickGetImageFilename.restype = ctypes.POINTER(ctypes.c_char) + _magick.MagickGetImageFilename.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImageFilename = _magick.MagickGetImageFilename +# MagickGetImageChannelStatistics +try: + _magick.MagickGetImageChannelStatistics.restype = ChannelStatistics + _magick.MagickGetImageChannelStatistics.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImageChannelStatistics = _magick.MagickGetImageChannelStatistics +# MagickGetResourceLimit +try: + _magick.MagickGetResourceLimit.restype = ctypes.c_ulong + _magick.MagickGetResourceLimit.argtypes = (ResourceType,) +except AttributeError,e: + pass +else: + MagickGetResourceLimit = _magick.MagickGetResourceLimit +# MagickGetResource +try: + _magick.MagickGetResource.restype = ctypes.c_ulong + _magick.MagickGetResource.argtypes = (ResourceType,) +except AttributeError,e: + pass +else: + MagickGetResource = _magick.MagickGetResource +# MagickGetCompressionQuality +try: + _magick.MagickGetCompressionQuality.restype = ctypes.c_ulong + _magick.MagickGetCompressionQuality.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetCompressionQuality = _magick.MagickGetCompressionQuality +# MagickRemoveImageProfile +try: + _magick.MagickRemoveImageProfile.restype = ctypes.POINTER(ctypes.c_ubyte) + _magick.MagickRemoveImageProfile.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char),size_t) +except AttributeError,e: + pass +else: + MagickRemoveImageProfile = _magick.MagickRemoveImageProfile +# MagickGetImageProfile +try: + _magick.MagickGetImageProfile.restype = ctypes.POINTER(ctypes.c_ubyte) + _magick.MagickGetImageProfile.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char),size_t) +except AttributeError,e: + pass +else: + MagickGetImageProfile = _magick.MagickGetImageProfile +# MagickGetBackgroundColor +try: + _magick.MagickGetBackgroundColor.restype = PixelWand + _magick.MagickGetBackgroundColor.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetBackgroundColor = _magick.MagickGetBackgroundColor +# MagickSetType +try: + _magick.MagickSetType.restype = MagickBooleanType + _magick.MagickSetType.argtypes = (MagickWand,ImageType) +except AttributeError,e: + pass +else: + MagickSetType = _magick.MagickSetType +# MagickSetSizeOffset +try: + _magick.MagickSetSizeOffset.restype = MagickBooleanType + _magick.MagickSetSizeOffset.argtypes = (MagickWand,ctypes.c_ulong,ctypes.c_ulong,ctypes.c_long) +except AttributeError,e: + pass +else: + MagickSetSizeOffset = _magick.MagickSetSizeOffset +# MagickSetSize +try: + _magick.MagickSetSize.restype = MagickBooleanType + _magick.MagickSetSize.argtypes = (MagickWand,ctypes.c_ulong,ctypes.c_ulong) +except AttributeError,e: + pass +else: + MagickSetSize = _magick.MagickSetSize +# MagickSetSamplingFactors +try: + _magick.MagickSetSamplingFactors.restype = MagickBooleanType + _magick.MagickSetSamplingFactors.argtypes = (MagickWand,ctypes.c_ulong,ctypes.POINTER(ctypes.c_double)) +except AttributeError,e: + pass +else: + MagickSetSamplingFactors = _magick.MagickSetSamplingFactors +# MagickSetResourceLimit +try: + _magick.MagickSetResourceLimit.restype = MagickBooleanType + _magick.MagickSetResourceLimit.argtypes = (ResourceType,ctypes.c_ulonglong) +except AttributeError,e: + pass +else: + MagickSetResourceLimit = _magick.MagickSetResourceLimit +# MagickSetResolution +try: + _magick.MagickSetResolution.restype = MagickBooleanType + _magick.MagickSetResolution.argtypes = (MagickWand,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickSetResolution = _magick.MagickSetResolution +# MagickSetPassphrase +try: + _magick.MagickSetPassphrase.restype = MagickBooleanType + _magick.MagickSetPassphrase.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickSetPassphrase = _magick.MagickSetPassphrase +# MagickSetPage +try: + _magick.MagickSetPage.restype = MagickBooleanType + _magick.MagickSetPage.argtypes = (MagickWand,ctypes.c_ulong,ctypes.c_ulong,ctypes.c_long,ctypes.c_long) +except AttributeError,e: + pass +else: + MagickSetPage = _magick.MagickSetPage +# MagickSetOrientation +try: + _magick.MagickSetOrientation.restype = MagickBooleanType + _magick.MagickSetOrientation.argtypes = (MagickWand,OrientationType) +except AttributeError,e: + pass +else: + MagickSetOrientation = _magick.MagickSetOrientation +# MagickSetOption +try: + _magick.MagickSetOption.restype = MagickBooleanType + _magick.MagickSetOption.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char),ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickSetOption = _magick.MagickSetOption +# MagickSetInterpolateMethod +try: + _magick.MagickSetInterpolateMethod.restype = MagickBooleanType + _magick.MagickSetInterpolateMethod.argtypes = (MagickWand,InterpolatePixelMethod) +except AttributeError,e: + pass +else: + MagickSetInterpolateMethod = _magick.MagickSetInterpolateMethod +# MagickSetInterlaceScheme +try: + _magick.MagickSetInterlaceScheme.restype = MagickBooleanType + _magick.MagickSetInterlaceScheme.argtypes = (MagickWand,InterlaceType) +except AttributeError,e: + pass +else: + MagickSetInterlaceScheme = _magick.MagickSetInterlaceScheme +# MagickSetImageProperty +try: + _magick.MagickSetImageProperty.restype = MagickBooleanType + _magick.MagickSetImageProperty.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char),ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickSetImageProperty = _magick.MagickSetImageProperty +# MagickSetImageProfile +try: + _magick.MagickSetImageProfile.restype = MagickBooleanType + _magick.MagickSetImageProfile.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char),ctypes.c_void_p,ctypes.c_ulong) +except AttributeError,e: + pass +else: + MagickSetImageProfile = _magick.MagickSetImageProfile +# MagickSetFormat +try: + _magick.MagickSetFormat.restype = MagickBooleanType + _magick.MagickSetFormat.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickSetFormat = _magick.MagickSetFormat +# MagickSetFilename +try: + _magick.MagickSetFilename.restype = MagickBooleanType + _magick.MagickSetFilename.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickSetFilename = _magick.MagickSetFilename +# MagickSetDepth +try: + _magick.MagickSetDepth.restype = MagickBooleanType + _magick.MagickSetDepth.argtypes = (MagickWand,ctypes.c_ulong) +except AttributeError,e: + pass +else: + MagickSetDepth = _magick.MagickSetDepth +# MagickSetCompressionQuality +try: + _magick.MagickSetCompressionQuality.restype = MagickBooleanType + _magick.MagickSetCompressionQuality.argtypes = (MagickWand,ctypes.c_ulong) +except AttributeError,e: + pass +else: + MagickSetCompressionQuality = _magick.MagickSetCompressionQuality +# MagickSetCompression +try: + _magick.MagickSetCompression.restype = MagickBooleanType + _magick.MagickSetCompression.argtypes = (MagickWand,CompressionType) +except AttributeError,e: + pass +else: + MagickSetCompression = _magick.MagickSetCompression +# MagickSetBackgroundColor +try: + _magick.MagickSetBackgroundColor.restype = MagickBooleanType + _magick.MagickSetBackgroundColor.argtypes = (MagickWand,PixelWand) +except AttributeError,e: + pass +else: + MagickSetBackgroundColor = _magick.MagickSetBackgroundColor +# MagickSetAntialias +try: + _magick.MagickSetAntialias.restype = MagickBooleanType + _magick.MagickSetAntialias.argtypes = (MagickWand,MagickBooleanType) +except AttributeError,e: + pass +else: + MagickSetAntialias = _magick.MagickSetAntialias +# MagickProfileImage +try: + _magick.MagickProfileImage.restype = MagickBooleanType + _magick.MagickProfileImage.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char),ctypes.c_void_p,ctypes.c_ulong) +except AttributeError,e: + pass +else: + MagickProfileImage = _magick.MagickProfileImage +# MagickGetSizeOffset +try: + _magick.MagickGetSizeOffset.restype = MagickBooleanType + _magick.MagickGetSizeOffset.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_long)) +except AttributeError,e: + pass +else: + MagickGetSizeOffset = _magick.MagickGetSizeOffset +# MagickGetSize +try: + _magick.MagickGetSize.restype = MagickBooleanType + _magick.MagickGetSize.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_ulong),ctypes.POINTER(ctypes.c_ulong)) +except AttributeError,e: + pass +else: + MagickGetSize = _magick.MagickGetSize +# MagickGetPage +try: + _magick.MagickGetPage.restype = MagickBooleanType + _magick.MagickGetPage.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_ulong),ctypes.POINTER(ctypes.c_ulong),ctypes.POINTER(ctypes.c_long),ctypes.POINTER(ctypes.c_long)) +except AttributeError,e: + pass +else: + MagickGetPage = _magick.MagickGetPage +# MagickGetAntialias +try: + _magick.MagickGetAntialias.restype = MagickBooleanType + _magick.MagickGetAntialias.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetAntialias = _magick.MagickGetAntialias +# MagickDeleteImageProperty +try: + _magick.MagickDeleteImageProperty.restype = MagickBooleanType + _magick.MagickDeleteImageProperty.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickDeleteImageProperty = _magick.MagickDeleteImageProperty +# MagickDeleteOption +try: + _magick.MagickDeleteOption.restype = MagickBooleanType + _magick.MagickDeleteOption.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickDeleteOption = _magick.MagickDeleteOption +# MagickGetInterpolateMethod +try: + _magick.MagickGetInterpolateMethod.restype = InterpolatePixelMethod + _magick.MagickGetInterpolateMethod.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetInterpolateMethod = _magick.MagickGetInterpolateMethod +# MagickGetInterlaceScheme +try: + _magick.MagickGetInterlaceScheme.restype = InterlaceType + _magick.MagickGetInterlaceScheme.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetInterlaceScheme = _magick.MagickGetInterlaceScheme +# MagickGetType +try: + _magick.MagickGetType.restype = ImageType + _magick.MagickGetType.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetType = _magick.MagickGetType +# MagickQueryMultilineFontMetrics +try: + _magick.MagickQueryMultilineFontMetrics.restype = ctypes.POINTER(ctypes.c_double) + _magick.MagickQueryMultilineFontMetrics.argtypes = (MagickWand,DrawingWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickQueryMultilineFontMetrics = _magick.MagickQueryMultilineFontMetrics +# MagickQueryFontMetrics +try: + _magick.MagickQueryFontMetrics.restype = ctypes.POINTER(ctypes.c_double) + _magick.MagickQueryFontMetrics.argtypes = (MagickWand,DrawingWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickQueryFontMetrics = _magick.MagickQueryFontMetrics +# MagickGetSamplingFactors +try: + _magick.MagickGetSamplingFactors.restype = ctypes.POINTER(ctypes.c_double) + _magick.MagickGetSamplingFactors.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_ulong)) +except AttributeError,e: + pass +else: + MagickGetSamplingFactors = _magick.MagickGetSamplingFactors +# MagickGetVersion +try: + _magick.MagickGetVersion.restype = ctypes.POINTER(ctypes.c_char) + _magick.MagickGetVersion.argtypes = (ctypes.POINTER(ctypes.c_ulong),) +except AttributeError,e: + pass +else: + MagickGetVersion = _magick.MagickGetVersion +# MagickGetReleaseDate +try: + _magick.MagickGetReleaseDate.restype = ctypes.POINTER(ctypes.c_char) + _magick.MagickGetReleaseDate.argtypes = () +except AttributeError,e: + pass +else: + MagickGetReleaseDate = _magick.MagickGetReleaseDate +# MagickGetQuantumRange +try: + _magick.MagickGetQuantumRange.restype = ctypes.POINTER(ctypes.c_char) + _magick.MagickGetQuantumRange.argtypes = (ctypes.POINTER(ctypes.c_ulong),) +except AttributeError,e: + pass +else: + MagickGetQuantumRange = _magick.MagickGetQuantumRange +# MagickGetQuantumDepth +try: + _magick.MagickGetQuantumDepth.restype = ctypes.POINTER(ctypes.c_char) + _magick.MagickGetQuantumDepth.argtypes = (ctypes.POINTER(ctypes.c_ulong),) +except AttributeError,e: + pass +else: + MagickGetQuantumDepth = _magick.MagickGetQuantumDepth +# MagickGetPackageName +try: + _magick.MagickGetPackageName.restype = ctypes.POINTER(ctypes.c_char) + _magick.MagickGetPackageName.argtypes = () +except AttributeError,e: + pass +else: + MagickGetPackageName = _magick.MagickGetPackageName +# MagickGetCopyright +try: + _magick.MagickGetCopyright.restype = ctypes.POINTER(ctypes.c_char) + _magick.MagickGetCopyright.argtypes = () +except AttributeError,e: + pass +else: + MagickGetCopyright = _magick.MagickGetCopyright +# MagickGetCompression +try: + _magick.MagickGetCompression.restype = CompressionType + _magick.MagickGetCompression.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetCompression = _magick.MagickGetCompression +# MagickQueryFormats +try: + _magick.MagickQueryFormats.restype = ctypes.POINTER(ctypes.POINTER(ctypes.c_char)) + _magick.MagickQueryFormats.argtypes = (ctypes.POINTER(ctypes.c_char),ctypes.POINTER(ctypes.c_ulong)) +except AttributeError,e: + pass +else: + MagickQueryFormats = _magick.MagickQueryFormats +# MagickQueryFonts +try: + _magick.MagickQueryFonts.restype = ctypes.POINTER(ctypes.POINTER(ctypes.c_char)) + _magick.MagickQueryFonts.argtypes = (ctypes.POINTER(ctypes.c_char),ctypes.POINTER(ctypes.c_ulong)) +except AttributeError,e: + pass +else: + MagickQueryFonts = _magick.MagickQueryFonts +# MagickQueryConfigureOptions +try: + _magick.MagickQueryConfigureOptions.restype = ctypes.POINTER(ctypes.POINTER(ctypes.c_char)) + _magick.MagickQueryConfigureOptions.argtypes = (ctypes.POINTER(ctypes.c_char),ctypes.POINTER(ctypes.c_ulong)) +except AttributeError,e: + pass +else: + MagickQueryConfigureOptions = _magick.MagickQueryConfigureOptions +# MagickQueryConfigureOption +try: + _magick.MagickQueryConfigureOption.restype = ctypes.POINTER(ctypes.c_char) + _magick.MagickQueryConfigureOption.argtypes = (ctypes.POINTER(ctypes.c_char),) +except AttributeError,e: + pass +else: + MagickQueryConfigureOption = _magick.MagickQueryConfigureOption +# MagickGetOptions +try: + _magick.MagickGetOptions.restype = ctypes.POINTER(ctypes.POINTER(ctypes.c_char)) + _magick.MagickGetOptions.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char),ctypes.POINTER(ctypes.c_ulong)) +except AttributeError,e: + pass +else: + MagickGetOptions = _magick.MagickGetOptions +# MagickGetOption +try: + _magick.MagickGetOption.restype = ctypes.POINTER(ctypes.c_char) + _magick.MagickGetOption.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickGetOption = _magick.MagickGetOption +# MagickGetImageProperties +try: + _magick.MagickGetImageProperties.restype = ctypes.POINTER(ctypes.POINTER(ctypes.c_char)) + _magick.MagickGetImageProperties.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char),ctypes.POINTER(ctypes.c_ulong)) +except AttributeError,e: + pass +else: + MagickGetImageProperties = _magick.MagickGetImageProperties +# MagickGetImageProperty +try: + _magick.MagickGetImageProperty.restype = ctypes.POINTER(ctypes.c_char) + _magick.MagickGetImageProperty.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickGetImageProperty = _magick.MagickGetImageProperty +# MagickGetImageProfiles +try: + _magick.MagickGetImageProfiles.restype = ctypes.POINTER(ctypes.POINTER(ctypes.c_char)) + _magick.MagickGetImageProfiles.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char),ctypes.POINTER(ctypes.c_ulong)) +except AttributeError,e: + pass +else: + MagickGetImageProfiles = _magick.MagickGetImageProfiles +# MagickGetHomeURL +try: + _magick.MagickGetHomeURL.restype = ctypes.POINTER(ctypes.c_char) + _magick.MagickGetHomeURL.argtypes = () +except AttributeError,e: + pass +else: + MagickGetHomeURL = _magick.MagickGetHomeURL +# MagickGetFormat +try: + _magick.MagickGetFormat.restype = ctypes.POINTER(ctypes.c_char) + _magick.MagickGetFormat.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetFormat = _magick.MagickGetFormat +# MagickGetFilename +try: + _magick.MagickGetFilename.restype = ctypes.POINTER(ctypes.c_char) + _magick.MagickGetFilename.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetFilename = _magick.MagickGetFilename +# DrawSetStrokeAlpha +try: + _magick.DrawSetStrokeAlpha.restype = None + _magick.DrawSetStrokeAlpha.argtypes = (DrawingWand,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawSetStrokeAlpha = _magick.DrawSetStrokeAlpha +# DrawSetFillAlpha +try: + _magick.DrawSetFillAlpha.restype = None + _magick.DrawSetFillAlpha.argtypes = (DrawingWand,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawSetFillAlpha = _magick.DrawSetFillAlpha +# DrawPushGraphicContext +try: + _magick.DrawPushGraphicContext.restype = None + _magick.DrawPushGraphicContext.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawPushGraphicContext = _magick.DrawPushGraphicContext +# DrawPopGraphicContext +try: + _magick.DrawPopGraphicContext.restype = None + _magick.DrawPopGraphicContext.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawPopGraphicContext = _magick.DrawPopGraphicContext +# MagickSetImageVirtualPixelMethod +try: + _magick.MagickSetImageVirtualPixelMethod.restype = VirtualPixelMethod + _magick.MagickSetImageVirtualPixelMethod.argtypes = (MagickWand,VirtualPixelMethod) +except AttributeError,e: + pass +else: + MagickSetImageVirtualPixelMethod = _magick.MagickSetImageVirtualPixelMethod +# MagickWriteImageBlob +try: + _magick.MagickWriteImageBlob.restype = ctypes.POINTER(ctypes.c_ubyte) + _magick.MagickWriteImageBlob.argtypes = (MagickWand,size_t) +except AttributeError,e: + pass +else: + MagickWriteImageBlob = _magick.MagickWriteImageBlob +# MagickGetImageSize +try: + _magick.MagickGetImageSize.restype = MagickSizeType + _magick.MagickGetImageSize.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImageSize = _magick.MagickGetImageSize +# MagickRegionOfInterestImage +try: + _magick.MagickRegionOfInterestImage.restype = MagickWand + _magick.MagickRegionOfInterestImage.argtypes = (MagickWand,ctypes.c_ulong,ctypes.c_ulong,ctypes.c_long,ctypes.c_long) +except AttributeError,e: + pass +else: + MagickRegionOfInterestImage = _magick.MagickRegionOfInterestImage +# MagickMosaicImages +try: + _magick.MagickMosaicImages.restype = MagickWand + _magick.MagickMosaicImages.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickMosaicImages = _magick.MagickMosaicImages +# MagickFlattenImages +try: + _magick.MagickFlattenImages.restype = MagickWand + _magick.MagickFlattenImages.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickFlattenImages = _magick.MagickFlattenImages +# MagickTransparentImage +try: + _magick.MagickTransparentImage.restype = MagickBooleanType + _magick.MagickTransparentImage.argtypes = (MagickWand,PixelWand,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickTransparentImage = _magick.MagickTransparentImage +# MagickSetImageOption +try: + _magick.MagickSetImageOption.restype = MagickBooleanType + _magick.MagickSetImageOption.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char),ctypes.POINTER(ctypes.c_char),ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickSetImageOption = _magick.MagickSetImageOption +# MagickSetImageIndex +try: + _magick.MagickSetImageIndex.restype = MagickBooleanType + _magick.MagickSetImageIndex.argtypes = (MagickWand,ctypes.c_long) +except AttributeError,e: + pass +else: + MagickSetImageIndex = _magick.MagickSetImageIndex +# MagickSetImageAttribute +try: + _magick.MagickSetImageAttribute.restype = MagickBooleanType + _magick.MagickSetImageAttribute.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char),ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickSetImageAttribute = _magick.MagickSetImageAttribute +# MagickOpaqueImage +try: + _magick.MagickOpaqueImage.restype = MagickBooleanType + _magick.MagickOpaqueImage.argtypes = (MagickWand,PixelWand,PixelWand,ctypes.c_double) +except AttributeError,e: + pass +else: + MagickOpaqueImage = _magick.MagickOpaqueImage +# MagickMatteFloodfillImage +try: + _magick.MagickMatteFloodfillImage.restype = MagickBooleanType + _magick.MagickMatteFloodfillImage.argtypes = (MagickWand,ctypes.c_double,ctypes.c_double,PixelWand,ctypes.c_long,ctypes.c_long) +except AttributeError,e: + pass +else: + MagickMatteFloodfillImage = _magick.MagickMatteFloodfillImage +# MagickGetImageExtrema +try: + _magick.MagickGetImageExtrema.restype = MagickBooleanType + _magick.MagickGetImageExtrema.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_ulong),ctypes.POINTER(ctypes.c_ulong)) +except AttributeError,e: + pass +else: + MagickGetImageExtrema = _magick.MagickGetImageExtrema +# MagickGetImageChannelExtrema +try: + _magick.MagickGetImageChannelExtrema.restype = MagickBooleanType + _magick.MagickGetImageChannelExtrema.argtypes = (MagickWand,ChannelType,ctypes.POINTER(ctypes.c_ulong),ctypes.POINTER(ctypes.c_ulong)) +except AttributeError,e: + pass +else: + MagickGetImageChannelExtrema = _magick.MagickGetImageChannelExtrema +# MagickColorFloodfillImage +try: + _magick.MagickColorFloodfillImage.restype = MagickBooleanType + _magick.MagickColorFloodfillImage.argtypes = (MagickWand,PixelWand,ctypes.c_double,PixelWand,ctypes.c_long,ctypes.c_long) +except AttributeError,e: + pass +else: + MagickColorFloodfillImage = _magick.MagickColorFloodfillImage +# MagickClipPathImage +try: + _magick.MagickClipPathImage.restype = MagickBooleanType + _magick.MagickClipPathImage.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char),MagickBooleanType) +except AttributeError,e: + pass +else: + MagickClipPathImage = _magick.MagickClipPathImage +# MagickGetImageIndex +try: + _magick.MagickGetImageIndex.restype = ctypes.c_long + _magick.MagickGetImageIndex.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickGetImageIndex = _magick.MagickGetImageIndex +# MagickGetImageAttribute +try: + _magick.MagickGetImageAttribute.restype = ctypes.POINTER(ctypes.c_char) + _magick.MagickGetImageAttribute.argtypes = (MagickWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + MagickGetImageAttribute = _magick.MagickGetImageAttribute +# MagickDescribeImage +try: + _magick.MagickDescribeImage.restype = ctypes.POINTER(ctypes.c_char) + _magick.MagickDescribeImage.argtypes = (MagickWand,) +except AttributeError,e: + pass +else: + MagickDescribeImage = _magick.MagickDescribeImage +# DrawPeekGraphicWand +try: + _magick.DrawPeekGraphicWand.restype = DrawInfo + _magick.DrawPeekGraphicWand.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawPeekGraphicWand = _magick.DrawPeekGraphicWand +# DrawGetStrokeAlpha +try: + _magick.DrawGetStrokeAlpha.restype = ctypes.c_double + _magick.DrawGetStrokeAlpha.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawGetStrokeAlpha = _magick.DrawGetStrokeAlpha +# DrawGetFillAlpha +try: + _magick.DrawGetFillAlpha.restype = ctypes.c_double + _magick.DrawGetFillAlpha.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawGetFillAlpha = _magick.DrawGetFillAlpha +# DrawTranslate +try: + _magick.DrawTranslate.restype = None + _magick.DrawTranslate.argtypes = (DrawingWand,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawTranslate = _magick.DrawTranslate +# DrawSkewY +try: + _magick.DrawSkewY.restype = None + _magick.DrawSkewY.argtypes = (DrawingWand,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawSkewY = _magick.DrawSkewY +# DrawSkewX +try: + _magick.DrawSkewX.restype = None + _magick.DrawSkewX.argtypes = (DrawingWand,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawSkewX = _magick.DrawSkewX +# DrawSetViewbox +try: + _magick.DrawSetViewbox.restype = None + _magick.DrawSetViewbox.argtypes = (DrawingWand,ctypes.c_ulong,ctypes.c_ulong,ctypes.c_ulong,ctypes.c_ulong) +except AttributeError,e: + pass +else: + DrawSetViewbox = _magick.DrawSetViewbox +# DrawSetTextUnderColor +try: + _magick.DrawSetTextUnderColor.restype = None + _magick.DrawSetTextUnderColor.argtypes = (DrawingWand,PixelWand) +except AttributeError,e: + pass +else: + DrawSetTextUnderColor = _magick.DrawSetTextUnderColor +# DrawSetTextEncoding +try: + _magick.DrawSetTextEncoding.restype = None + _magick.DrawSetTextEncoding.argtypes = (DrawingWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + DrawSetTextEncoding = _magick.DrawSetTextEncoding +# DrawSetTextDecoration +try: + _magick.DrawSetTextDecoration.restype = None + _magick.DrawSetTextDecoration.argtypes = (DrawingWand,DecorationType) +except AttributeError,e: + pass +else: + DrawSetTextDecoration = _magick.DrawSetTextDecoration +# DrawSetTextAntialias +try: + _magick.DrawSetTextAntialias.restype = None + _magick.DrawSetTextAntialias.argtypes = (DrawingWand,MagickBooleanType) +except AttributeError,e: + pass +else: + DrawSetTextAntialias = _magick.DrawSetTextAntialias +# DrawSetTextAlignment +try: + _magick.DrawSetTextAlignment.restype = None + _magick.DrawSetTextAlignment.argtypes = (DrawingWand,AlignType) +except AttributeError,e: + pass +else: + DrawSetTextAlignment = _magick.DrawSetTextAlignment +# DrawSetStrokeWidth +try: + _magick.DrawSetStrokeWidth.restype = None + _magick.DrawSetStrokeWidth.argtypes = (DrawingWand,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawSetStrokeWidth = _magick.DrawSetStrokeWidth +# DrawSetStrokeOpacity +try: + _magick.DrawSetStrokeOpacity.restype = None + _magick.DrawSetStrokeOpacity.argtypes = (DrawingWand,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawSetStrokeOpacity = _magick.DrawSetStrokeOpacity +# DrawSetStrokeMiterLimit +try: + _magick.DrawSetStrokeMiterLimit.restype = None + _magick.DrawSetStrokeMiterLimit.argtypes = (DrawingWand,ctypes.c_ulong) +except AttributeError,e: + pass +else: + DrawSetStrokeMiterLimit = _magick.DrawSetStrokeMiterLimit +# DrawSetStrokeLineJoin +try: + _magick.DrawSetStrokeLineJoin.restype = None + _magick.DrawSetStrokeLineJoin.argtypes = (DrawingWand,LineJoin) +except AttributeError,e: + pass +else: + DrawSetStrokeLineJoin = _magick.DrawSetStrokeLineJoin +# DrawSetStrokeLineCap +try: + _magick.DrawSetStrokeLineCap.restype = None + _magick.DrawSetStrokeLineCap.argtypes = (DrawingWand,LineCap) +except AttributeError,e: + pass +else: + DrawSetStrokeLineCap = _magick.DrawSetStrokeLineCap +# DrawSetStrokeDashOffset +try: + _magick.DrawSetStrokeDashOffset.restype = None + _magick.DrawSetStrokeDashOffset.argtypes = (DrawingWand,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawSetStrokeDashOffset = _magick.DrawSetStrokeDashOffset +# DrawSetStrokeColor +try: + _magick.DrawSetStrokeColor.restype = None + _magick.DrawSetStrokeColor.argtypes = (DrawingWand,PixelWand) +except AttributeError,e: + pass +else: + DrawSetStrokeColor = _magick.DrawSetStrokeColor +# DrawSetStrokeAntialias +try: + _magick.DrawSetStrokeAntialias.restype = None + _magick.DrawSetStrokeAntialias.argtypes = (DrawingWand,MagickBooleanType) +except AttributeError,e: + pass +else: + DrawSetStrokeAntialias = _magick.DrawSetStrokeAntialias +# DrawSetGravity +try: + _magick.DrawSetGravity.restype = None + _magick.DrawSetGravity.argtypes = (DrawingWand,GravityType) +except AttributeError,e: + pass +else: + DrawSetGravity = _magick.DrawSetGravity +# DrawSetFontWeight +try: + _magick.DrawSetFontWeight.restype = None + _magick.DrawSetFontWeight.argtypes = (DrawingWand,ctypes.c_ulong) +except AttributeError,e: + pass +else: + DrawSetFontWeight = _magick.DrawSetFontWeight +# DrawSetFontStyle +try: + _magick.DrawSetFontStyle.restype = None + _magick.DrawSetFontStyle.argtypes = (DrawingWand,StyleType) +except AttributeError,e: + pass +else: + DrawSetFontStyle = _magick.DrawSetFontStyle +# DrawSetFontStretch +try: + _magick.DrawSetFontStretch.restype = None + _magick.DrawSetFontStretch.argtypes = (DrawingWand,StretchType) +except AttributeError,e: + pass +else: + DrawSetFontStretch = _magick.DrawSetFontStretch +# DrawSetFontSize +try: + _magick.DrawSetFontSize.restype = None + _magick.DrawSetFontSize.argtypes = (DrawingWand,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawSetFontSize = _magick.DrawSetFontSize +# DrawSetFillRule +try: + _magick.DrawSetFillRule.restype = None + _magick.DrawSetFillRule.argtypes = (DrawingWand,FillRule) +except AttributeError,e: + pass +else: + DrawSetFillRule = _magick.DrawSetFillRule +# DrawSetFillOpacity +try: + _magick.DrawSetFillOpacity.restype = None + _magick.DrawSetFillOpacity.argtypes = (DrawingWand,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawSetFillOpacity = _magick.DrawSetFillOpacity +# DrawSetFillColor +try: + _magick.DrawSetFillColor.restype = None + _magick.DrawSetFillColor.argtypes = (DrawingWand,PixelWand) +except AttributeError,e: + pass +else: + DrawSetFillColor = _magick.DrawSetFillColor +# DrawSetClipUnits +try: + _magick.DrawSetClipUnits.restype = None + _magick.DrawSetClipUnits.argtypes = (DrawingWand,ClipPathUnits) +except AttributeError,e: + pass +else: + DrawSetClipUnits = _magick.DrawSetClipUnits +# DrawSetClipRule +try: + _magick.DrawSetClipRule.restype = None + _magick.DrawSetClipRule.argtypes = (DrawingWand,FillRule) +except AttributeError,e: + pass +else: + DrawSetClipRule = _magick.DrawSetClipRule +# DrawScale +try: + _magick.DrawScale.restype = None + _magick.DrawScale.argtypes = (DrawingWand,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawScale = _magick.DrawScale +# DrawRoundRectangle +try: + _magick.DrawRoundRectangle.restype = None + _magick.DrawRoundRectangle.argtypes = (DrawingWand,ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawRoundRectangle = _magick.DrawRoundRectangle +# DrawRotate +try: + _magick.DrawRotate.restype = None + _magick.DrawRotate.argtypes = (DrawingWand,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawRotate = _magick.DrawRotate +# DrawResetVectorGraphics +try: + _magick.DrawResetVectorGraphics.restype = None + _magick.DrawResetVectorGraphics.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawResetVectorGraphics = _magick.DrawResetVectorGraphics +# DrawRectangle +try: + _magick.DrawRectangle.restype = None + _magick.DrawRectangle.argtypes = (DrawingWand,ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawRectangle = _magick.DrawRectangle +# DrawPushDefs +try: + _magick.DrawPushDefs.restype = None + _magick.DrawPushDefs.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawPushDefs = _magick.DrawPushDefs +# DrawPushClipPath +try: + _magick.DrawPushClipPath.restype = None + _magick.DrawPushClipPath.argtypes = (DrawingWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + DrawPushClipPath = _magick.DrawPushClipPath +# DrawPopDefs +try: + _magick.DrawPopDefs.restype = None + _magick.DrawPopDefs.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawPopDefs = _magick.DrawPopDefs +# DrawPopClipPath +try: + _magick.DrawPopClipPath.restype = None + _magick.DrawPopClipPath.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawPopClipPath = _magick.DrawPopClipPath +# DrawPolyline +try: + _magick.DrawPolyline.restype = None + _magick.DrawPolyline.argtypes = (DrawingWand,ctypes.c_ulong,PointInfo) +except AttributeError,e: + pass +else: + DrawPolyline = _magick.DrawPolyline +# DrawPolygon +try: + _magick.DrawPolygon.restype = None + _magick.DrawPolygon.argtypes = (DrawingWand,ctypes.c_ulong,PointInfo) +except AttributeError,e: + pass +else: + DrawPolygon = _magick.DrawPolygon +# DrawPoint +try: + _magick.DrawPoint.restype = None + _magick.DrawPoint.argtypes = (DrawingWand,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawPoint = _magick.DrawPoint +# DrawPathStart +try: + _magick.DrawPathStart.restype = None + _magick.DrawPathStart.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawPathStart = _magick.DrawPathStart +# DrawPathMoveToRelative +try: + _magick.DrawPathMoveToRelative.restype = None + _magick.DrawPathMoveToRelative.argtypes = (DrawingWand,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawPathMoveToRelative = _magick.DrawPathMoveToRelative +# DrawPathMoveToAbsolute +try: + _magick.DrawPathMoveToAbsolute.restype = None + _magick.DrawPathMoveToAbsolute.argtypes = (DrawingWand,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawPathMoveToAbsolute = _magick.DrawPathMoveToAbsolute +# DrawPathLineToVerticalRelative +try: + _magick.DrawPathLineToVerticalRelative.restype = None + _magick.DrawPathLineToVerticalRelative.argtypes = (DrawingWand,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawPathLineToVerticalRelative = _magick.DrawPathLineToVerticalRelative +# DrawPathLineToVerticalAbsolute +try: + _magick.DrawPathLineToVerticalAbsolute.restype = None + _magick.DrawPathLineToVerticalAbsolute.argtypes = (DrawingWand,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawPathLineToVerticalAbsolute = _magick.DrawPathLineToVerticalAbsolute +# DrawPathLineToHorizontalRelative +try: + _magick.DrawPathLineToHorizontalRelative.restype = None + _magick.DrawPathLineToHorizontalRelative.argtypes = (DrawingWand,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawPathLineToHorizontalRelative = _magick.DrawPathLineToHorizontalRelative +# DrawPathLineToHorizontalAbsolute +try: + _magick.DrawPathLineToHorizontalAbsolute.restype = None + _magick.DrawPathLineToHorizontalAbsolute.argtypes = (DrawingWand,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawPathLineToHorizontalAbsolute = _magick.DrawPathLineToHorizontalAbsolute +# DrawPathLineToRelative +try: + _magick.DrawPathLineToRelative.restype = None + _magick.DrawPathLineToRelative.argtypes = (DrawingWand,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawPathLineToRelative = _magick.DrawPathLineToRelative +# DrawPathLineToAbsolute +try: + _magick.DrawPathLineToAbsolute.restype = None + _magick.DrawPathLineToAbsolute.argtypes = (DrawingWand,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawPathLineToAbsolute = _magick.DrawPathLineToAbsolute +# DrawPathFinish +try: + _magick.DrawPathFinish.restype = None + _magick.DrawPathFinish.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawPathFinish = _magick.DrawPathFinish +# DrawPathEllipticArcRelative +try: + _magick.DrawPathEllipticArcRelative.restype = None + _magick.DrawPathEllipticArcRelative.argtypes = (DrawingWand,ctypes.c_double,ctypes.c_double,ctypes.c_double,MagickBooleanType,MagickBooleanType,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawPathEllipticArcRelative = _magick.DrawPathEllipticArcRelative +# DrawPathEllipticArcAbsolute +try: + _magick.DrawPathEllipticArcAbsolute.restype = None + _magick.DrawPathEllipticArcAbsolute.argtypes = (DrawingWand,ctypes.c_double,ctypes.c_double,ctypes.c_double,MagickBooleanType,MagickBooleanType,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawPathEllipticArcAbsolute = _magick.DrawPathEllipticArcAbsolute +# DrawPathCurveToSmoothRelative +try: + _magick.DrawPathCurveToSmoothRelative.restype = None + _magick.DrawPathCurveToSmoothRelative.argtypes = (DrawingWand,ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawPathCurveToSmoothRelative = _magick.DrawPathCurveToSmoothRelative +# DrawPathCurveToSmoothAbsolute +try: + _magick.DrawPathCurveToSmoothAbsolute.restype = None + _magick.DrawPathCurveToSmoothAbsolute.argtypes = (DrawingWand,ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawPathCurveToSmoothAbsolute = _magick.DrawPathCurveToSmoothAbsolute +# DrawPathCurveToQuadraticBezierSmoothRelative +try: + _magick.DrawPathCurveToQuadraticBezierSmoothRelative.restype = None + _magick.DrawPathCurveToQuadraticBezierSmoothRelative.argtypes = (DrawingWand,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawPathCurveToQuadraticBezierSmoothRelative = _magick.DrawPathCurveToQuadraticBezierSmoothRelative +# DrawPathCurveToQuadraticBezierSmoothAbsolute +try: + _magick.DrawPathCurveToQuadraticBezierSmoothAbsolute.restype = None + _magick.DrawPathCurveToQuadraticBezierSmoothAbsolute.argtypes = (DrawingWand,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawPathCurveToQuadraticBezierSmoothAbsolute = _magick.DrawPathCurveToQuadraticBezierSmoothAbsolute +# DrawPathCurveToQuadraticBezierRelative +try: + _magick.DrawPathCurveToQuadraticBezierRelative.restype = None + _magick.DrawPathCurveToQuadraticBezierRelative.argtypes = (DrawingWand,ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawPathCurveToQuadraticBezierRelative = _magick.DrawPathCurveToQuadraticBezierRelative +# DrawPathCurveToQuadraticBezierAbsolute +try: + _magick.DrawPathCurveToQuadraticBezierAbsolute.restype = None + _magick.DrawPathCurveToQuadraticBezierAbsolute.argtypes = (DrawingWand,ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawPathCurveToQuadraticBezierAbsolute = _magick.DrawPathCurveToQuadraticBezierAbsolute +# DrawPathCurveToRelative +try: + _magick.DrawPathCurveToRelative.restype = None + _magick.DrawPathCurveToRelative.argtypes = (DrawingWand,ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawPathCurveToRelative = _magick.DrawPathCurveToRelative +# DrawPathCurveToAbsolute +try: + _magick.DrawPathCurveToAbsolute.restype = None + _magick.DrawPathCurveToAbsolute.argtypes = (DrawingWand,ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawPathCurveToAbsolute = _magick.DrawPathCurveToAbsolute +# DrawPathClose +try: + _magick.DrawPathClose.restype = None + _magick.DrawPathClose.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawPathClose = _magick.DrawPathClose +# DrawMatte +try: + _magick.DrawMatte.restype = None + _magick.DrawMatte.argtypes = (DrawingWand,ctypes.c_double,ctypes.c_double,PaintMethod) +except AttributeError,e: + pass +else: + DrawMatte = _magick.DrawMatte +# DrawLine +try: + _magick.DrawLine.restype = None + _magick.DrawLine.argtypes = (DrawingWand,ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawLine = _magick.DrawLine +# DrawGetTextUnderColor +try: + _magick.DrawGetTextUnderColor.restype = None + _magick.DrawGetTextUnderColor.argtypes = (DrawingWand,PixelWand) +except AttributeError,e: + pass +else: + DrawGetTextUnderColor = _magick.DrawGetTextUnderColor +# DrawGetStrokeColor +try: + _magick.DrawGetStrokeColor.restype = None + _magick.DrawGetStrokeColor.argtypes = (DrawingWand,PixelWand) +except AttributeError,e: + pass +else: + DrawGetStrokeColor = _magick.DrawGetStrokeColor +# DrawGetFillColor +try: + _magick.DrawGetFillColor.restype = None + _magick.DrawGetFillColor.argtypes = (DrawingWand,PixelWand) +except AttributeError,e: + pass +else: + DrawGetFillColor = _magick.DrawGetFillColor +# DrawEllipse +try: + _magick.DrawEllipse.restype = None + _magick.DrawEllipse.argtypes = (DrawingWand,ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawEllipse = _magick.DrawEllipse +# DrawComment +try: + _magick.DrawComment.restype = None + _magick.DrawComment.argtypes = (DrawingWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + DrawComment = _magick.DrawComment +# DrawColor +try: + _magick.DrawColor.restype = None + _magick.DrawColor.argtypes = (DrawingWand,ctypes.c_double,ctypes.c_double,PaintMethod) +except AttributeError,e: + pass +else: + DrawColor = _magick.DrawColor +# DrawCircle +try: + _magick.DrawCircle.restype = None + _magick.DrawCircle.argtypes = (DrawingWand,ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawCircle = _magick.DrawCircle +# DrawBezier +try: + _magick.DrawBezier.restype = None + _magick.DrawBezier.argtypes = (DrawingWand,ctypes.c_ulong,PointInfo) +except AttributeError,e: + pass +else: + DrawBezier = _magick.DrawBezier +# DrawArc +try: + _magick.DrawArc.restype = None + _magick.DrawArc.argtypes = (DrawingWand,ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawArc = _magick.DrawArc +# DrawAnnotation +try: + _magick.DrawAnnotation.restype = None + _magick.DrawAnnotation.argtypes = (DrawingWand,ctypes.c_double,ctypes.c_double,ctypes.POINTER(ctypes.c_ubyte)) +except AttributeError,e: + pass +else: + DrawAnnotation = _magick.DrawAnnotation +# DrawAffine +try: + _magick.DrawAffine.restype = None + _magick.DrawAffine.argtypes = (DrawingWand,AffineMatrix) +except AttributeError,e: + pass +else: + DrawAffine = _magick.DrawAffine +# ClearDrawingWand +try: + _magick.ClearDrawingWand.restype = None + _magick.ClearDrawingWand.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + ClearDrawingWand = _magick.ClearDrawingWand +# DrawGetStrokeMiterLimit +try: + _magick.DrawGetStrokeMiterLimit.restype = ctypes.c_ulong + _magick.DrawGetStrokeMiterLimit.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawGetStrokeMiterLimit = _magick.DrawGetStrokeMiterLimit +# DrawGetFontWeight +try: + _magick.DrawGetFontWeight.restype = ctypes.c_ulong + _magick.DrawGetFontWeight.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawGetFontWeight = _magick.DrawGetFontWeight +# DrawGetFontStyle +try: + _magick.DrawGetFontStyle.restype = StyleType + _magick.DrawGetFontStyle.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawGetFontStyle = _magick.DrawGetFontStyle +# DrawGetFontStretch +try: + _magick.DrawGetFontStretch.restype = StretchType + _magick.DrawGetFontStretch.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawGetFontStretch = _magick.DrawGetFontStretch +# PushDrawingWand +try: + _magick.PushDrawingWand.restype = MagickBooleanType + _magick.PushDrawingWand.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + PushDrawingWand = _magick.PushDrawingWand +# PopDrawingWand +try: + _magick.PopDrawingWand.restype = MagickBooleanType + _magick.PopDrawingWand.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + PopDrawingWand = _magick.PopDrawingWand +# IsDrawingWand +try: + _magick.IsDrawingWand.restype = MagickBooleanType + _magick.IsDrawingWand.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + IsDrawingWand = _magick.IsDrawingWand +# DrawSetVectorGraphics +try: + _magick.DrawSetVectorGraphics.restype = MagickBooleanType + _magick.DrawSetVectorGraphics.argtypes = (DrawingWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + DrawSetVectorGraphics = _magick.DrawSetVectorGraphics +# DrawSetStrokePatternURL +try: + _magick.DrawSetStrokePatternURL.restype = MagickBooleanType + _magick.DrawSetStrokePatternURL.argtypes = (DrawingWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + DrawSetStrokePatternURL = _magick.DrawSetStrokePatternURL +# DrawSetStrokeDashArray +try: + _magick.DrawSetStrokeDashArray.restype = MagickBooleanType + _magick.DrawSetStrokeDashArray.argtypes = (DrawingWand,ctypes.c_ulong,ctypes.POINTER(ctypes.c_double)) +except AttributeError,e: + pass +else: + DrawSetStrokeDashArray = _magick.DrawSetStrokeDashArray +# DrawSetFontFamily +try: + _magick.DrawSetFontFamily.restype = MagickBooleanType + _magick.DrawSetFontFamily.argtypes = (DrawingWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + DrawSetFontFamily = _magick.DrawSetFontFamily +# DrawSetFont +try: + _magick.DrawSetFont.restype = MagickBooleanType + _magick.DrawSetFont.argtypes = (DrawingWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + DrawSetFont = _magick.DrawSetFont +# DrawSetFillPatternURL +try: + _magick.DrawSetFillPatternURL.restype = MagickBooleanType + _magick.DrawSetFillPatternURL.argtypes = (DrawingWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + DrawSetFillPatternURL = _magick.DrawSetFillPatternURL +# DrawSetClipPath +try: + _magick.DrawSetClipPath.restype = MagickBooleanType + _magick.DrawSetClipPath.argtypes = (DrawingWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + DrawSetClipPath = _magick.DrawSetClipPath +# DrawRender +try: + _magick.DrawRender.restype = MagickBooleanType + _magick.DrawRender.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawRender = _magick.DrawRender +# DrawPushPattern +try: + _magick.DrawPushPattern.restype = MagickBooleanType + _magick.DrawPushPattern.argtypes = (DrawingWand,ctypes.POINTER(ctypes.c_char),ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.c_double) +except AttributeError,e: + pass +else: + DrawPushPattern = _magick.DrawPushPattern +# DrawPopPattern +try: + _magick.DrawPopPattern.restype = MagickBooleanType + _magick.DrawPopPattern.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawPopPattern = _magick.DrawPopPattern +# DrawGetTextAntialias +try: + _magick.DrawGetTextAntialias.restype = MagickBooleanType + _magick.DrawGetTextAntialias.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawGetTextAntialias = _magick.DrawGetTextAntialias +# DrawGetStrokeAntialias +try: + _magick.DrawGetStrokeAntialias.restype = MagickBooleanType + _magick.DrawGetStrokeAntialias.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawGetStrokeAntialias = _magick.DrawGetStrokeAntialias +# DrawComposite +try: + _magick.DrawComposite.restype = MagickBooleanType + _magick.DrawComposite.argtypes = (DrawingWand,CompositeOperator,ctypes.c_double,ctypes.c_double,ctypes.c_double,ctypes.c_double,MagickWand) +except AttributeError,e: + pass +else: + DrawComposite = _magick.DrawComposite +# DrawClearException +try: + _magick.DrawClearException.restype = MagickBooleanType + _magick.DrawClearException.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawClearException = _magick.DrawClearException +# DrawGetStrokeLineJoin +try: + _magick.DrawGetStrokeLineJoin.restype = LineJoin + _magick.DrawGetStrokeLineJoin.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawGetStrokeLineJoin = _magick.DrawGetStrokeLineJoin +# DrawGetStrokeLineCap +try: + _magick.DrawGetStrokeLineCap.restype = LineCap + _magick.DrawGetStrokeLineCap.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawGetStrokeLineCap = _magick.DrawGetStrokeLineCap +# DrawGetGravity +try: + _magick.DrawGetGravity.restype = GravityType + _magick.DrawGetGravity.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawGetGravity = _magick.DrawGetGravity +# DrawGetFillRule +try: + _magick.DrawGetFillRule.restype = FillRule + _magick.DrawGetFillRule.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawGetFillRule = _magick.DrawGetFillRule +# DrawGetClipRule +try: + _magick.DrawGetClipRule.restype = FillRule + _magick.DrawGetClipRule.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawGetClipRule = _magick.DrawGetClipRule +# DrawGetExceptionType +try: + _magick.DrawGetExceptionType.restype = ExceptionType + _magick.DrawGetExceptionType.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawGetExceptionType = _magick.DrawGetExceptionType +# NewDrawingWand +try: + _magick.NewDrawingWand.restype = DrawingWand + _magick.NewDrawingWand.argtypes = () +except AttributeError,e: + pass +else: + NewDrawingWand = _magick.NewDrawingWand +# DrawAllocateWand +try: + _magick.DrawAllocateWand.restype = DrawingWand + _magick.DrawAllocateWand.argtypes = (DrawInfo,Image) +except AttributeError,e: + pass +else: + DrawAllocateWand = _magick.DrawAllocateWand +# DestroyDrawingWand +try: + _magick.DestroyDrawingWand.restype = DrawingWand + _magick.DestroyDrawingWand.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DestroyDrawingWand = _magick.DestroyDrawingWand +# CloneDrawingWand +try: + _magick.CloneDrawingWand.restype = DrawingWand + _magick.CloneDrawingWand.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + CloneDrawingWand = _magick.CloneDrawingWand +# PeekDrawingWand +try: + _magick.PeekDrawingWand.restype = DrawInfo + _magick.PeekDrawingWand.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + PeekDrawingWand = _magick.PeekDrawingWand +# DrawGetStrokeWidth +try: + _magick.DrawGetStrokeWidth.restype = ctypes.c_double + _magick.DrawGetStrokeWidth.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawGetStrokeWidth = _magick.DrawGetStrokeWidth +# DrawGetStrokeOpacity +try: + _magick.DrawGetStrokeOpacity.restype = ctypes.c_double + _magick.DrawGetStrokeOpacity.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawGetStrokeOpacity = _magick.DrawGetStrokeOpacity +# DrawGetStrokeDashOffset +try: + _magick.DrawGetStrokeDashOffset.restype = ctypes.c_double + _magick.DrawGetStrokeDashOffset.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawGetStrokeDashOffset = _magick.DrawGetStrokeDashOffset +# DrawGetStrokeDashArray +try: + _magick.DrawGetStrokeDashArray.restype = ctypes.POINTER(ctypes.c_double) + _magick.DrawGetStrokeDashArray.argtypes = (DrawingWand,ctypes.POINTER(ctypes.c_ulong)) +except AttributeError,e: + pass +else: + DrawGetStrokeDashArray = _magick.DrawGetStrokeDashArray +# DrawGetFontSize +try: + _magick.DrawGetFontSize.restype = ctypes.c_double + _magick.DrawGetFontSize.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawGetFontSize = _magick.DrawGetFontSize +# DrawGetFillOpacity +try: + _magick.DrawGetFillOpacity.restype = ctypes.c_double + _magick.DrawGetFillOpacity.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawGetFillOpacity = _magick.DrawGetFillOpacity +# DrawGetTextDecoration +try: + _magick.DrawGetTextDecoration.restype = DecorationType + _magick.DrawGetTextDecoration.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawGetTextDecoration = _magick.DrawGetTextDecoration +# DrawGetClipUnits +try: + _magick.DrawGetClipUnits.restype = ClipPathUnits + _magick.DrawGetClipUnits.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawGetClipUnits = _magick.DrawGetClipUnits +# DrawGetVectorGraphics +try: + _magick.DrawGetVectorGraphics.restype = ctypes.POINTER(ctypes.c_char) + _magick.DrawGetVectorGraphics.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawGetVectorGraphics = _magick.DrawGetVectorGraphics +# DrawGetTextEncoding +try: + _magick.DrawGetTextEncoding.restype = ctypes.POINTER(ctypes.c_char) + _magick.DrawGetTextEncoding.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawGetTextEncoding = _magick.DrawGetTextEncoding +# DrawGetFontFamily +try: + _magick.DrawGetFontFamily.restype = ctypes.POINTER(ctypes.c_char) + _magick.DrawGetFontFamily.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawGetFontFamily = _magick.DrawGetFontFamily +# DrawGetFont +try: + _magick.DrawGetFont.restype = ctypes.POINTER(ctypes.c_char) + _magick.DrawGetFont.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawGetFont = _magick.DrawGetFont +# DrawGetException +try: + _magick.DrawGetException.restype = ctypes.POINTER(ctypes.c_char) + _magick.DrawGetException.argtypes = (DrawingWand,ctypes.POINTER(ExceptionType)) +except AttributeError,e: + pass +else: + DrawGetException = _magick.DrawGetException +# DrawGetClipPath +try: + _magick.DrawGetClipPath.restype = ctypes.POINTER(ctypes.c_char) + _magick.DrawGetClipPath.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawGetClipPath = _magick.DrawGetClipPath +# DrawGetTextAlignment +try: + _magick.DrawGetTextAlignment.restype = AlignType + _magick.DrawGetTextAlignment.argtypes = (DrawingWand,) +except AttributeError,e: + pass +else: + DrawGetTextAlignment = _magick.DrawGetTextAlignment +# PixelSetMagickColor +try: + _magick.PixelSetMagickColor.restype = None + _magick.PixelSetMagickColor.argtypes = (PixelWand,MagickPixelPacket) +except AttributeError,e: + pass +else: + PixelSetMagickColor = _magick.PixelSetMagickColor +# PixelSetColorFromWand +try: + _magick.PixelSetColorFromWand.restype = None + _magick.PixelSetColorFromWand.argtypes = (PixelWand,PixelWand) +except AttributeError,e: + pass +else: + PixelSetColorFromWand = _magick.PixelSetColorFromWand +# PixelGetMagickColor +try: + _magick.PixelGetMagickColor.restype = None + _magick.PixelGetMagickColor.argtypes = (PixelWand,MagickPixelPacket) +except AttributeError,e: + pass +else: + PixelGetMagickColor = _magick.PixelGetMagickColor +# ClearPixelWand +try: + _magick.ClearPixelWand.restype = None + _magick.ClearPixelWand.argtypes = (PixelWand,) +except AttributeError,e: + pass +else: + ClearPixelWand = _magick.ClearPixelWand +# NewPixelWands +try: + _magick.NewPixelWands.restype = ctypes.POINTER(PixelWand) + _magick.NewPixelWands.argtypes = (ctypes.c_ulong,) +except AttributeError,e: + pass +else: + NewPixelWands = _magick.NewPixelWands +# NewPixelWand +try: + _magick.NewPixelWand.restype = PixelWand + _magick.NewPixelWand.argtypes = () +except AttributeError,e: + pass +else: + NewPixelWand = _magick.NewPixelWand +# DestroyPixelWands +try: + _magick.DestroyPixelWands.restype = ctypes.POINTER(PixelWand) + _magick.DestroyPixelWands.argtypes = (ctypes.POINTER(PixelWand),ctypes.c_ulong) +except AttributeError,e: + pass +else: + DestroyPixelWands = _magick.DestroyPixelWands +# DestroyPixelWand +try: + _magick.DestroyPixelWand.restype = PixelWand + _magick.DestroyPixelWand.argtypes = (PixelWand,) +except AttributeError,e: + pass +else: + DestroyPixelWand = _magick.DestroyPixelWand +# IsPixelWandSimilar +try: + _magick.IsPixelWandSimilar.restype = MagickBooleanType + _magick.IsPixelWandSimilar.argtypes = (PixelWand,PixelWand,ctypes.c_double) +except AttributeError,e: + pass +else: + IsPixelWandSimilar = _magick.IsPixelWandSimilar +# IsPixelWand +try: + _magick.IsPixelWand.restype = MagickBooleanType + _magick.IsPixelWand.argtypes = (PixelWand,) +except AttributeError,e: + pass +else: + IsPixelWand = _magick.IsPixelWand + +# PixelSetColor +try: + _magick.PixelSetColor.restype = MagickBooleanType + _magick.PixelSetColor.argtypes = (PixelWand,ctypes.POINTER(ctypes.c_char)) +except AttributeError,e: + pass +else: + PixelSetColor = _magick.PixelSetColor + + +if __name__=='__main__': + import doctest + doctest.testmod() diff --git a/src/calibre/utils/fontconfig.py b/src/calibre/utils/fontconfig.py index e9f27b961c..93ee9f6566 100644 --- a/src/calibre/utils/fontconfig.py +++ b/src/calibre/utils/fontconfig.py @@ -22,7 +22,7 @@ match to a given font specification. The main functions in this module are: .. autofunction:: match ''' -import sys, os, locale, codecs, ctypes +import sys, os, locale, codecs from ctypes import cdll, c_void_p, Structure, c_int, POINTER, c_ubyte, c_char, util, \ pointer, byref, create_string_buffer, Union, c_char_p, c_double diff --git a/src/calibre/terminfo.py b/src/calibre/utils/terminfo.py similarity index 83% rename from src/calibre/terminfo.py rename to src/calibre/utils/terminfo.py index 121f5fcfd1..075c0e694d 100644 --- a/src/calibre/terminfo.py +++ b/src/calibre/utils/terminfo.py @@ -163,36 +163,50 @@ class ProgressBar: The progress bar is colored, if the terminal supports color output; and adjusts to the width of the terminal. + + If the terminal doesn't have the required capabilities, it uses a + simple progress bar. """ BAR = '%3d%% ${GREEN}[${BOLD}%s%s${NORMAL}${GREEN}]${NORMAL}\n' HEADER = '${BOLD}${CYAN}%s${NORMAL}\n\n' - def __init__(self, term, header): - self.term = term - if not (self.term.CLEAR_EOL and self.term.UP and self.term.BOL): - raise ValueError("Terminal isn't capable enough -- you " - "should use a simpler progress dispaly.") - self.width = self.term.COLS or 75 - self.bar = term.render(self.BAR) - self.header = self.term.render(self.HEADER % header.center(self.width)) - self.cleared = 1 #: true if we haven't drawn the bar yet. + def __init__(self, term, header, no_progress_bar = False): + self.term, self.no_progress_bar = term, no_progress_bar + self.fancy = self.term.CLEAR_EOL and self.term.UP and self.term.BOL + if self.fancy: + self.width = self.term.COLS or 75 + self.bar = term.render(self.BAR) + self.header = self.term.render(self.HEADER % header.center(self.width)) + self.cleared = 1 #: true if we haven't drawn the bar yet. def update(self, percent, message=''): if isinstance(message, unicode): - message = message.encode('utf-8', 'ignore') - if self.cleared: - sys.stdout.write(self.header) - self.cleared = 0 - n = int((self.width-10)*percent) - msg = message.center(self.width) - sys.stdout.write( - self.term.BOL + self.term.UP + self.term.CLEAR_EOL + - (self.bar % (100*percent, '='*n, '-'*(self.width-10-n))) + - self.term.CLEAR_EOL + msg) - sys.stdout.flush() + message = message.encode('utf-8', 'replace') + + if self.no_progress_bar: + if message: + print message + elif self.fancy: + if self.cleared: + sys.stdout.write(self.header) + self.cleared = 0 + n = int((self.width-10)*percent) + msg = message.center(self.width) + sys.stdout.write( + self.term.BOL + self.term.UP + self.term.CLEAR_EOL + + (self.bar % (100*percent, '='*n, '-'*(self.width-10-n))) + + self.term.CLEAR_EOL + msg) + sys.stdout.flush() + else: + if not message: + print '%d%%'%(percent*100), + else: + print '%d%%'%(percent*100), message + sys.stdout.flush() + def clear(self): - if not self.cleared: + if self.fancy and not self.cleared: sys.stdout.write(self.term.BOL + self.term.CLEAR_EOL + self.term.UP + self.term.CLEAR_EOL + self.term.UP + self.term.CLEAR_EOL) diff --git a/src/calibre/threadpool.py b/src/calibre/utils/threadpool.py similarity index 100% rename from src/calibre/threadpool.py rename to src/calibre/utils/threadpool.py diff --git a/src/calibre/web/feeds/main.py b/src/calibre/web/feeds/main.py index 33554eb0b1..7d2547360d 100644 --- a/src/calibre/web/feeds/main.py +++ b/src/calibre/web/feeds/main.py @@ -60,35 +60,15 @@ If you specify this option, any argument to %prog is ignored and a default recip return p -def simple_progress_bar(percent, msg): - if isinstance(msg, unicode): - msg = msg.encode('utf-8', 'ignore') - if not msg: - print '%d%%'%(percent*100), - else: - print '%d%%'%(percent*100), msg - sys.stdout.flush() - -def no_progress_bar(percent, msg): - print msg - class RecipeError(Exception): pass def run_recipe(opts, recipe_arg, parser, notification=None, handler=None): if notification is None: - from calibre.terminfo import TerminalController, ProgressBar + from calibre.utils.terminfo import TerminalController, ProgressBar term = TerminalController(sys.stdout) - if opts.progress_bar: - try: - pb = ProgressBar(term, _('Fetching feeds...')) - notification = pb.update - except ValueError: - notification = simple_progress_bar - print _('Fetching feeds...') - else: - notification = no_progress_bar - + pb = ProgressBar(term, _('Fetching feeds...'), no_progress_bar=opts.progress_bar) + notification = pb.update recipe, is_profile = None, False if opts.feeds is not None: diff --git a/src/calibre/web/feeds/news.py b/src/calibre/web/feeds/news.py index 06ab13d913..9cc7139b28 100644 --- a/src/calibre/web/feeds/news.py +++ b/src/calibre/web/feeds/news.py @@ -20,7 +20,7 @@ from calibre.ebooks.metadata import MetaInformation from calibre.web.feeds import feed_from_xml, templates, feeds_from_index from calibre.web.fetch.simple import option_parser as web2disk_option_parser from calibre.web.fetch.simple import RecursiveFetcher -from calibre.threadpool import WorkRequest, ThreadPool, NoResultsPending +from calibre.utils.threadpool import WorkRequest, ThreadPool, NoResultsPending from calibre.ebooks.lrf.web.profiles import FullContentProfile from calibre.ptempfile import PersistentTemporaryFile From 57de47dbee8e33081784c6c964b6141a54db14c9 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 30 Jul 2008 08:58:49 -0700 Subject: [PATCH 29/34] IGN:... --- src/calibre/ebooks/lrf/comic/convert_from.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/calibre/ebooks/lrf/comic/convert_from.py b/src/calibre/ebooks/lrf/comic/convert_from.py index 2462253f7c..9d05c03da1 100755 --- a/src/calibre/ebooks/lrf/comic/convert_from.py +++ b/src/calibre/ebooks/lrf/comic/convert_from.py @@ -36,11 +36,21 @@ PROFILES = { } def extract_comic(path_to_comic_file): + ''' + Un-archive the comic file. + ''' tdir = PersistentTemporaryDirectory(suffix='comic_extract') extract(path_to_comic_file, tdir) return tdir def find_pages(dir, sort_on_mtime=False, verbose=False): + ''' + Find valid comic pages in a previously un-archived comic. + + :param dir: Directory in which extracted comic lives + :param sort_on_mtime: If True sort pages based on their last modified time. + Otherwise, sort alphabetically. + ''' extensions = ['jpeg', 'jpg', 'gif', 'png'] pages = [] for datum in os.walk(dir): @@ -62,6 +72,10 @@ def find_pages(dir, sort_on_mtime=False, verbose=False): return pages class PageProcessor(list): + ''' + Contains the actual image rendering logic. See :method:`__call__` and + :method:`process_pages`. + ''' def __init__(self, path_to_page, dest, opts, num): self.path_to_page = path_to_page @@ -181,6 +195,9 @@ class Progress(object): _('Rendered %s')%os.path.basename(req.callable.path_to_page)) def process_pages(pages, opts, update): + ''' + Render all identified comic pages. + ''' initialize() try: tdir = PersistentTemporaryDirectory('_comic2lrf_pp') @@ -295,4 +312,4 @@ def main(args=sys.argv, notification=None): return 0 if __name__ == '__main__': - sys.exit(main()) + sys.exit(main()) \ No newline at end of file From 60263f36432dd5f44d3833d684d476ed1e1e477c Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 30 Jul 2008 12:12:51 -0700 Subject: [PATCH 30/34] Add config option to ask for confirmation on deletes --- installer/osx/freeze.py | 8 ++++++-- src/calibre/gui2/dialogs/config.py | 2 ++ src/calibre/gui2/dialogs/config.ui | 9 ++++++++- src/calibre/gui2/main.py | 6 ++++++ 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/installer/osx/freeze.py b/installer/osx/freeze.py index 24be7aec0a..e35e302d32 100644 --- a/installer/osx/freeze.py +++ b/installer/osx/freeze.py @@ -45,8 +45,10 @@ print >>loader, 'from %(module)s import %(function)s' print >>loader, '%(function)s()' loader.close() os.chmod(loader_path, 0700) -os.environ['PYTHONHOME'] = resources_dir -os.environ['FC_CONFIG_DIR'] = os.path.join(resources_dir, 'fonts') +os.environ['PYTHONHOME'] = resources_dir +os.environ['FC_CONFIG_DIR'] = os.path.join(resources_dir, 'fonts') +os.environ['MAGICK_HOME'] = os.path.join(frameworks_dir, 'ImageMagick') +os.environ['DYLD_LIBRARY_PATH'] = os.path.join(frameworks_dir, 'ImageMagick', 'lib') os.execv(loader_path, sys.argv) ''' CHECK_SYMLINKS_PRESCRIPT = \ @@ -325,6 +327,8 @@ def main(): 'NSHumanReadableCopyright':'Copyright 2008, Kovid Goyal', 'LSEnvironment':{ 'FC_CONFIG_DIR':'@executable_path/../Resources/fonts', + 'MAGICK_HOME':'@executable_path/../Frameworks/ImageMagick', + 'DYLD_LIBRARY_PATH':'@executable_path/../Frameworks/ImageMagick/lib', } }, }, diff --git a/src/calibre/gui2/dialogs/config.py b/src/calibre/gui2/dialogs/config.py index 6c6caddda9..e4379deb56 100644 --- a/src/calibre/gui2/dialogs/config.py +++ b/src/calibre/gui2/dialogs/config.py @@ -67,6 +67,7 @@ class ConfigDialog(QDialog, Ui_Dialog): single_format = settings.get('save to disk single format', 'lrf') self.single_format.setCurrentIndex(BOOK_EXTENSIONS.index(single_format)) self.cover_browse.setValue(settings.get('cover flow queue length', 6)) + self.confirm_delete.setChecked(settings.get('confirm delete', False)) def compact(self, toggled): d = Vacuum(self, self.db) @@ -96,6 +97,7 @@ class ConfigDialog(QDialog, Ui_Dialog): self.final_columns = [self.columns.item(i).checkState() == Qt.Checked for i in range(self.columns.count())] settings.set('toolbar icon size', self.ICON_SIZES[self.toolbar_button_size.currentIndex()]) settings.set('show text in toolbar', bool(self.show_toolbar_text.isChecked())) + settings.set('confirm delete', bool(self.confirm_delete.isChecked())) pattern = self.filename_pattern.commit() settings.set('filename pattern', pattern) settings.set('save to disk single format', BOOK_EXTENSIONS[self.single_format.currentIndex()]) diff --git a/src/calibre/gui2/dialogs/config.ui b/src/calibre/gui2/dialogs/config.ui index 70d223446f..a8c24563d5 100644 --- a/src/calibre/gui2/dialogs/config.ui +++ b/src/calibre/gui2/dialogs/config.ui @@ -83,7 +83,7 @@ 0 0 595 - 638 + 640 @@ -156,6 +156,13 @@ + + + + Ask for &confirmation before deleting files + + + diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py index ab80b1e466..c1ca797d41 100644 --- a/src/calibre/gui2/main.py +++ b/src/calibre/gui2/main.py @@ -534,6 +534,12 @@ class Main(MainWindow, Ui_MainWindow): rows = view.selectionModel().selectedRows() if not rows or len(rows) == 0: return + if Settings().get('confirm delete', False): + d = question_dialog(self, _('Confirm delete'), + _('Are you sure you want to delete these %d books?')%len(rows)) + if d.exec_() != QMessageBox.Yes: + return + if self.stack.currentIndex() == 0: view.model().delete_books(rows) else: From 8944c7e9847e26536b446800c71fdaf23cf64e81 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 30 Jul 2008 12:33:28 -0700 Subject: [PATCH 31/34] Fix handling of EmpLine in lrf2lrs --- src/calibre/ebooks/lrf/objects.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/calibre/ebooks/lrf/objects.py b/src/calibre/ebooks/lrf/objects.py index e071b07f10..29c0d8de44 100644 --- a/src/calibre/ebooks/lrf/objects.py +++ b/src/calibre/ebooks/lrf/objects.py @@ -744,10 +744,9 @@ class Text(LRFStream): self.content.append(self.__class__.TextTag(name)) def empline(self, tag, stream): - def invalid(op): stream.seek(op) - self.simple_container(None, 'EmpLine') + #self.simple_container(None, 'EmpLine') oldpos = stream.tell() try: @@ -770,7 +769,8 @@ class Text(LRFStream): except LRFParseError: stream.seek(oldpos) - self.content.append(self.__class__.TextTag( + if attrs: + self.content.append(self.__class__.TextTag( 'EmpLine', attrs=attrs)) def space(self, tag, stream): From a05d1b3614613f3d5719e077c407f7d55b0ee696 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 30 Jul 2008 15:49:26 -0700 Subject: [PATCH 32/34] IGN:... --- installer/osx/freeze.py | 9 ++++++ src/calibre/ebooks/lrf/comic/convert_from.py | 34 ++++++++++++-------- src/calibre/utils/PythonMagickWand.py | 2 +- 3 files changed, 30 insertions(+), 15 deletions(-) mode change 100755 => 100644 src/calibre/utils/PythonMagickWand.py diff --git a/installer/osx/freeze.py b/installer/osx/freeze.py index e35e302d32..30fd2647a2 100644 --- a/installer/osx/freeze.py +++ b/installer/osx/freeze.py @@ -267,6 +267,15 @@ _check_symlinks_prescript() dst = os.path.join(resource_dir, 'lib', 'python2.5', 'IPython') if os.path.exists(dst): shutil.rmtree(dst) shutil.copytree(os.path.expanduser('~/build/ipython/IPython'), dst) + + print + print 'Adding ImageMagick' + dest = os.path.join(frameworks_dir, 'ImageMagick') + if os.path.exists(dest): + sutil.rmtree(dest) + shutil.copytree(os.path.expanduser('~/ImageMagick'), dest, True) + shutil.copyfile('/usr/local/lib/libpng12.0.dylib', os.path.join(dest, 'lib', 'libpng12.0.dylib')) + print print 'Installing prescipt' sf = [os.path.basename(s) for s in all_names] diff --git a/src/calibre/ebooks/lrf/comic/convert_from.py b/src/calibre/ebooks/lrf/comic/convert_from.py index 9d05c03da1..829e331526 100755 --- a/src/calibre/ebooks/lrf/comic/convert_from.py +++ b/src/calibre/ebooks/lrf/comic/convert_from.py @@ -16,20 +16,24 @@ from calibre.ptempfile import PersistentTemporaryDirectory from calibre.utils.threadpool import ThreadPool, WorkRequest from calibre.utils.terminfo import ProgressBar from calibre.ebooks.lrf.pylrs.pylrs import Book, BookSetting, ImageStream, ImageBlock -from calibre.utils.PythonMagickWand import \ - NewMagickWand, NewPixelWand, \ - MagickSetImageBorderColor, \ - MagickReadImage, MagickRotateImage, \ - MagickTrimImage, \ - MagickNormalizeImage, MagickGetImageWidth, \ - MagickGetImageHeight, \ - MagickResizeImage, MagickSetImageType, \ - GrayscaleType, CatromFilter, MagickSetImagePage, \ - MagickBorderImage, MagickSharpenImage, \ - MagickQuantizeImage, RGBColorspace, \ - MagickWriteImage, DestroyPixelWand, \ - DestroyMagickWand, CloneMagickWand, \ - MagickThumbnailImage, MagickCropImage, initialize, finalize +try: + from calibre.utils.PythonMagickWand import \ + NewMagickWand, NewPixelWand, \ + MagickSetImageBorderColor, \ + MagickReadImage, MagickRotateImage, \ + MagickTrimImage, \ + MagickNormalizeImage, MagickGetImageWidth, \ + MagickGetImageHeight, \ + MagickResizeImage, MagickSetImageType, \ + GrayscaleType, CatromFilter, MagickSetImagePage, \ + MagickBorderImage, MagickSharpenImage, \ + MagickQuantizeImage, RGBColorspace, \ + MagickWriteImage, DestroyPixelWand, \ + DestroyMagickWand, CloneMagickWand, \ + MagickThumbnailImage, MagickCropImage, initialize, finalize + _imagemagick_loaded = True +except: + _imagemagick_loaded = False PROFILES = { 'prs500':(584, 754), @@ -198,6 +202,8 @@ def process_pages(pages, opts, update): ''' Render all identified comic pages. ''' + if not _imagemagick_loaded: + raise RuntimeError('Failed to load ImageMagick') initialize() try: tdir = PersistentTemporaryDirectory('_comic2lrf_pp') diff --git a/src/calibre/utils/PythonMagickWand.py b/src/calibre/utils/PythonMagickWand.py old mode 100755 new mode 100644 index c0664b3573..cdb3337e24 --- a/src/calibre/utils/PythonMagickWand.py +++ b/src/calibre/utils/PythonMagickWand.py @@ -73,7 +73,7 @@ isosx = 'darwin' in sys.platform isfrozen = getattr(sys, 'frozen', False) if isosx: - _lib = os.path.join(getattr(sys, 'frameworks_dir'), 'ImageMagick', 'libWand.dylib') \ + _lib = os.path.join(getattr(sys, 'frameworks_dir'), 'ImageMagick', 'libMagickWand.dylib') \ if isfrozen else util.find_library('Wand') elif iswindows: _lib = os.path.join(os.path.dirname(sys.executable), 'ImageMagick', 'CORE_RL_wand_.dll') \ From 8eb9b269e4470cdb98da578f44ca3e596b571e9e Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 30 Jul 2008 16:39:39 -0700 Subject: [PATCH 33/34] Fix isbndb.exe unicode error on windows. --- src/calibre/ebooks/metadata/isbndb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/ebooks/metadata/isbndb.py b/src/calibre/ebooks/metadata/isbndb.py index 19ca54e282..ec81684ef2 100644 --- a/src/calibre/ebooks/metadata/isbndb.py +++ b/src/calibre/ebooks/metadata/isbndb.py @@ -140,7 +140,7 @@ def main(args=sys.argv): return 1 for book in create_books(opts, args): - print unicode(book) + print unicode(book).encode('utf-8') return 0 From 7e71f8648eaa6da7b59debe594e525c8d573e75f Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 30 Jul 2008 16:54:10 -0700 Subject: [PATCH 34/34] IGN:... --- installer/windows/freeze.py | 3 ++- src/calibre/utils/PythonMagickWand.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/installer/windows/freeze.py b/installer/windows/freeze.py index 4474776dc3..8d7f53228e 100644 --- a/installer/windows/freeze.py +++ b/installer/windows/freeze.py @@ -110,7 +110,8 @@ class BuildEXE(py2exe.build_exe.py2exe): print '\tAdding pdftohtml' shutil.copyfile(PDFTOHTML, os.path.join(PY2EXE_DIR, os.path.basename(PDFTOHTML))) print '\tAdding ImageMagick' - shutil.copytree(IMAGEMAGICK_DIR, os.path.join(PY2EXE_DIR, 'ImageMagick')) + for f in os.listdir(IMAGEMAGICK_DIR): + shutil.copyfile(os.path.join(IMAGEMAGICK_DIR, f), os.path.join(PY2EXE_DIR, f)) print '\tCopying fontconfig' for f in glob.glob(os.path.join(FONTCONFIG_DIR, '*')): tgt = os.path.join(PY2EXE_DIR, os.path.basename(f)) diff --git a/src/calibre/utils/PythonMagickWand.py b/src/calibre/utils/PythonMagickWand.py index cdb3337e24..e3e421fe55 100644 --- a/src/calibre/utils/PythonMagickWand.py +++ b/src/calibre/utils/PythonMagickWand.py @@ -76,7 +76,7 @@ if isosx: _lib = os.path.join(getattr(sys, 'frameworks_dir'), 'ImageMagick', 'libMagickWand.dylib') \ if isfrozen else util.find_library('Wand') elif iswindows: - _lib = os.path.join(os.path.dirname(sys.executable), 'ImageMagick', 'CORE_RL_wand_.dll') \ + _lib = os.path.join(os.path.dirname(sys.executable), 'CORE_RL_wand_.dll') \ if isfrozen else 'CORE_RL_wand_' else: _lib = util.find_library('MagickWand')