From 7a74dc34105aeb964c42d2e1bd613998ae06ef2e Mon Sep 17 00:00:00 2001 From: James Ralston <> Date: Sun, 7 Feb 2010 22:43:15 -0800 Subject: [PATCH 01/10] Initial CHM changes --- src/calibre/ebooks/chm/__init__.py | 8 + src/calibre/ebooks/chm/chm/__init__.py | 34 ++ src/calibre/ebooks/chm/chm/_chmlib.pyd | Bin 0 -> 92672 bytes src/calibre/ebooks/chm/chm/chm.py | 508 +++++++++++++++++++++++++ src/calibre/ebooks/chm/chm/chmlib.py | 93 +++++ src/calibre/ebooks/chm/chm/extra.pyd | Bin 0 -> 57856 bytes src/calibre/ebooks/chm/input.py | 348 +++++++++++++++++ 7 files changed, 991 insertions(+) create mode 100644 src/calibre/ebooks/chm/__init__.py create mode 100644 src/calibre/ebooks/chm/chm/__init__.py create mode 100644 src/calibre/ebooks/chm/chm/_chmlib.pyd create mode 100644 src/calibre/ebooks/chm/chm/chm.py create mode 100644 src/calibre/ebooks/chm/chm/chmlib.py create mode 100644 src/calibre/ebooks/chm/chm/extra.pyd create mode 100644 src/calibre/ebooks/chm/input.py diff --git a/src/calibre/ebooks/chm/__init__.py b/src/calibre/ebooks/chm/__init__.py new file mode 100644 index 0000000000..d7d77da4b6 --- /dev/null +++ b/src/calibre/ebooks/chm/__init__.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python +__license__ = 'GPL v3' +__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' +__docformat__ = 'restructuredtext en' + +''' +Used for chm input +''' diff --git a/src/calibre/ebooks/chm/chm/__init__.py b/src/calibre/ebooks/chm/chm/__init__.py new file mode 100644 index 0000000000..83fcb5c50e --- /dev/null +++ b/src/calibre/ebooks/chm/chm/__init__.py @@ -0,0 +1,34 @@ +## Copyright (C) 2003-2006 Rubens Ramos + +## pychm is free software; you can redistribute it and/or +## modify it under the terms of the GNU General Public License as +## published by the Free Software Foundation; either version 2 of the +## License, or (at your option) any later version. + +## This program 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. See the GNU +## General Public License for more details. + +## You should have received a copy of the GNU General Public +## License along with this program; see the file COPYING. If not, +## write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +## Boston, MA 02111-1307, USA + +## $Id: __init__.py,v 1.8 2006/06/18 10:50:43 rubensr Exp $ + +''' + chm - A package to manipulate CHM files + + The chm package provides four modules: chm, chmlib, extra and + _chmlib. _chmlib and chmlib are very low level libraries generated + from SWIG interface files, and are simple wrappers around the API + defined by the C library chmlib. + The extra module adds full-text search support. + the chm module provides some higher level classes to simplify + access to the CHM files information. +''' +__all__ = ["chm", "chmlib", "_chmlib", "extra"] +__version__ = "0.8.4" +__revision__ = "$Id: __init__.py,v 1.8 2006/06/18 10:50:43 rubensr Exp $" + diff --git a/src/calibre/ebooks/chm/chm/_chmlib.pyd b/src/calibre/ebooks/chm/chm/_chmlib.pyd new file mode 100644 index 0000000000000000000000000000000000000000..ef963bf87383906ead8118be45e1441506556f97 GIT binary patch literal 92672 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 + +## Based on code by: +## Copyright (C) 2003 Razvan Cojocaru + +## pychm is free software; you can redistribute it and/or +## modify it under the terms of the GNU General Public License as +## published by the Free Software Foundation; either version 2 of the +## License, or (at your option) any later version. + +## This program 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. See the GNU +## General Public License for more details. + +## You should have received a copy of the GNU General Public +## License along with this program; see the file COPYING. If not, +## write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +## Boston, MA 02111-1307, USA + +## $Id: chm.py,v 1.12 2006/08/07 12:31:51 rubensr Exp $ + +''' + chm - A high-level front end for the chmlib python module. + + The chm module provides high level access to the functionality + included in chmlib. It encapsulates functions in the CHMFile class, and + provides some additional features, such as the ability to obtain + the contents tree of a CHM archive. + +''' + +import chmlib +import extra +import array +import string +import os.path +import sys + +charset_table = { + 0 : 'iso8859_1', # ANSI_CHARSET + 238 : 'iso8859_2', # EASTEUROPE_CHARSET + 178 : 'iso8859_6', # ARABIC_CHARSET + 161 : 'iso8859_7', # GREEK_CHARSET + 177 : 'iso8859_8', # HEBREW_CHARSET + 162 : 'iso8859_9', # TURKISH_CHARSET + 222 : 'iso8859_11', # THAI_CHARSET - hmm not in python 2.2... + 186 : 'iso8859_13', # BALTIC_CHARSET + 204 : 'cp1251', # RUSSIAN_CHARSET + 255 : 'cp437', # OEM_CHARSET + 128 : 'cp932', # SHIFTJIS_CHARSET + 134 : 'cp936', # GB2312_CHARSET + 129 : 'cp949', # HANGUL_CHARSET + 136 : 'cp950', # CHINESEBIG5_CHARSET + 1 : None, # DEFAULT_CHARSET + 2 : None, # SYMBOL_CHARSET + 130 : None, # JOHAB_CHARSET + 163 : None, # VIETNAMESE_CHARSET + 77 : None, # MAC_CHARSET +} + +locale_table = { + 0x0436 : ('iso8859_1', "Afrikaans", "Western Europe & US"), + 0x041c : ('iso8859_2', "Albanian", "Central Europe"), + 0x0401 : ('iso8859_6', "Arabic_Saudi_Arabia", "Arabic"), + 0x0801 : ('iso8859_6', "Arabic_Iraq", "Arabic"), + 0x0c01 : ('iso8859_6', "Arabic_Egypt", "Arabic"), + 0x1001 : ('iso8859_6', "Arabic_Libya", "Arabic"), + 0x1401 : ('iso8859_6', "Arabic_Algeria", "Arabic"), + 0x1801 : ('iso8859_6', "Arabic_Morocco", "Arabic"), + 0x1c01 : ('iso8859_6', "Arabic_Tunisia", "Arabic"), + 0x2001 : ('iso8859_6', "Arabic_Oman", "Arabic"), + 0x2401 : ('iso8859_6', "Arabic_Yemen", "Arabic"), + 0x2801 : ('iso8859_6', "Arabic_Syria", "Arabic"), + 0x2c01 : ('iso8859_6', "Arabic_Jordan", "Arabic"), + 0x3001 : ('iso8859_6', "Arabic_Lebanon", "Arabic"), + 0x3401 : ('iso8859_6', "Arabic_Kuwait", "Arabic"), + 0x3801 : ('iso8859_6', "Arabic_UAE", "Arabic"), + 0x3c01 : ('iso8859_6', "Arabic_Bahrain", "Arabic"), + 0x4001 : ('iso8859_6', "Arabic_Qatar", "Arabic"), + 0x042b : (None, "Armenian","Armenian"), + 0x042c : ('iso8859_9', "Azeri_Latin", "Turkish"), + 0x082c : ('cp1251', "Azeri_Cyrillic", "Cyrillic"), + 0x042d : ('iso8859_1', "Basque", "Western Europe & US"), + 0x0423 : ('cp1251', "Belarusian", "Cyrillic"), + 0x0402 : ('cp1251', "Bulgarian", "Cyrillic"), + 0x0403 : ('iso8859_1', "Catalan", "Western Europe & US"), + 0x0404 : ('cp950', "Chinese_Taiwan", "Traditional Chinese"), + 0x0804 : ('cp936', "Chinese_PRC", "Simplified Chinese"), + 0x0c04 : ('cp950', "Chinese_Hong_Kong", "Traditional Chinese"), + 0x1004 : ('cp936', "Chinese_Singapore", "Simplified Chinese"), + 0x1404 : ('cp950', "Chinese_Macau", "Traditional Chinese"), + 0x041a : ('iso8859_2', "Croatian", "Central Europe"), + 0x0405 : ('iso8859_2', "Czech", "Central Europe"), + 0x0406 : ('iso8859_1', "Danish", "Western Europe & US"), + 0x0413 : ('iso8859_1', "Dutch_Standard", "Western Europe & US"), + 0x0813 : ('iso8859_1', "Dutch_Belgian", "Western Europe & US"), + 0x0409 : ('iso8859_1', "English_United_States", "Western Europe & US"), + 0x0809 : ('iso8859_1', "English_United_Kingdom", "Western Europe & US"), + 0x0c09 : ('iso8859_1', "English_Australian", "Western Europe & US"), + 0x1009 : ('iso8859_1', "English_Canadian", "Western Europe & US"), + 0x1409 : ('iso8859_1', "English_New_Zealand", "Western Europe & US"), + 0x1809 : ('iso8859_1', "English_Irish", "Western Europe & US"), + 0x1c09 : ('iso8859_1', "English_South_Africa", "Western Europe & US"), + 0x2009 : ('iso8859_1', "English_Jamaica", "Western Europe & US"), + 0x2409 : ('iso8859_1', "English_Caribbean", "Western Europe & US"), + 0x2809 : ('iso8859_1', "English_Belize", "Western Europe & US"), + 0x2c09 : ('iso8859_1', "English_Trinidad", "Western Europe & US"), + 0x3009 : ('iso8859_1', "English_Zimbabwe", "Western Europe & US"), + 0x3409 : ('iso8859_1', "English_Philippines", "Western Europe & US"), + 0x0425 : ('iso8859_13',"Estonian", "Baltic",), + 0x0438 : ('iso8859_1', "Faeroese", "Western Europe & US"), + 0x0429 : ('iso8859_6', "Farsi", "Arabic"), + 0x040b : ('iso8859_1', "Finnish", "Western Europe & US"), + 0x040c : ('iso8859_1', "French_Standard", "Western Europe & US"), + 0x080c : ('iso8859_1', "French_Belgian", "Western Europe & US"), + 0x0c0c : ('iso8859_1', "French_Canadian", "Western Europe & US"), + 0x100c : ('iso8859_1', "French_Swiss", "Western Europe & US"), + 0x140c : ('iso8859_1', "French_Luxembourg", "Western Europe & US"), + 0x180c : ('iso8859_1', "French_Monaco", "Western Europe & US"), + 0x0437 : (None, "Georgian", "Georgian"), + 0x0407 : ('iso8859_1', "German_Standard", "Western Europe & US"), + 0x0807 : ('iso8859_1', "German_Swiss", "Western Europe & US"), + 0x0c07 : ('iso8859_1', "German_Austrian", "Western Europe & US"), + 0x1007 : ('iso8859_1', "German_Luxembourg", "Western Europe & US"), + 0x1407 : ('iso8859_1', "German_Liechtenstein", "Western Europe & US"), + 0x0408 : ('iso8859_7', "Greek", "Greek"), + 0x040d : ('iso8859_8', "Hebrew", "Hebrew"), + 0x0439 : (None, "Hindi", "Indic"), + 0x040e : ('iso8859_2', "Hungarian", "Central Europe"), + 0x040f : ('iso8859_1', "Icelandic", "Western Europe & US"), + 0x0421 : ('iso8859_1', "Indonesian", "Western Europe & US"), + 0x0410 : ('iso8859_1', "Italian_Standard", "Western Europe & US"), + 0x0810 : ('iso8859_1', "Italian_Swiss", "Western Europe & US"), + 0x0411 : ('cp932', "Japanese", "Japanese"), + 0x043f : ('cp1251', "Kazakh", "Cyrillic"), + 0x0457 : (None, "Konkani", "Indic"), + 0x0412 : ('cp949', "Korean", "Korean"), + 0x0426 : ('iso8859_13',"Latvian", "Baltic",), + 0x0427 : ('iso8859_13',"Lithuanian", "Baltic",), + 0x042f : ('cp1251', "Macedonian", "Cyrillic"), + 0x043e : ('iso8859_1', "Malay_Malaysia", "Western Europe & US"), + 0x083e : ('iso8859_1', "Malay_Brunei_Darussalam", "Western Europe & US"), + 0x044e : (None, "Marathi", "Indic"), + 0x0414 : ('iso8859_1', "Norwegian_Bokmal", "Western Europe & US"), + 0x0814 : ('iso8859_1', "Norwegian_Nynorsk", "Western Europe & US"), + 0x0415 : ('iso8859_2', "Polish", "Central Europe"), + 0x0416 : ('iso8859_1', "Portuguese_Brazilian", "Western Europe & US"), + 0x0816 : ('iso8859_1', "Portuguese_Standard", "Western Europe & US"), + 0x0418 : ('iso8859_2', "Romanian", "Central Europe"), + 0x0419 : ('cp1251', "Russian", "Cyrillic"), + 0x044f : (None, "Sanskrit", "Indic"), + 0x081a : ('iso8859_2', "Serbian_Latin", "Central Europe"), + 0x0c1a : ('cp1251', "Serbian_Cyrillic", "Cyrillic"), + 0x041b : ('iso8859_2', "Slovak", "Central Europe"), + 0x0424 : ('iso8859_2', "Slovenian", "Central Europe"), + 0x040a : ('iso8859_1', "Spanish_Trad_Sort", "Western Europe & US"), + 0x080a : ('iso8859_1', "Spanish_Mexican", "Western Europe & US"), + 0x0c0a : ('iso8859_1', "Spanish_Modern_Sort", "Western Europe & US"), + 0x100a : ('iso8859_1', "Spanish_Guatemala", "Western Europe & US"), + 0x140a : ('iso8859_1', "Spanish_Costa_Rica", "Western Europe & US"), + 0x180a : ('iso8859_1', "Spanish_Panama", "Western Europe & US"), + 0x1c0a : ('iso8859_1', "Spanish_Dominican_Repub", "Western Europe & US"), + 0x200a : ('iso8859_1', "Spanish_Venezuela", "Western Europe & US"), + 0x240a : ('iso8859_1', "Spanish_Colombia", "Western Europe & US"), + 0x280a : ('iso8859_1', "Spanish_Peru", "Western Europe & US"), + 0x2c0a : ('iso8859_1', "Spanish_Argentina", "Western Europe & US"), + 0x300a : ('iso8859_1', "Spanish_Ecuador", "Western Europe & US"), + 0x340a : ('iso8859_1', "Spanish_Chile", "Western Europe & US"), + 0x380a : ('iso8859_1', "Spanish_Uruguay", "Western Europe & US"), + 0x3c0a : ('iso8859_1', "Spanish_Paraguay", "Western Europe & US"), + 0x400a : ('iso8859_1', "Spanish_Bolivia", "Western Europe & US"), + 0x440a : ('iso8859_1', "Spanish_El_Salvador", "Western Europe & US"), + 0x480a : ('iso8859_1', "Spanish_Honduras", "Western Europe & US"), + 0x4c0a : ('iso8859_1', "Spanish_Nicaragua", "Western Europe & US"), + 0x500a : ('iso8859_1', "Spanish_Puerto_Rico", "Western Europe & US"), + 0x0441 : ('iso8859_1', "Swahili", "Western Europe & US"), + 0x041d : ('iso8859_1', "Swedish", "Western Europe & US"), + 0x081d : ('iso8859_1', "Swedish_Finland", "Western Europe & US"), + 0x0449 : (None, "Tamil", "Indic"), + 0x0444 : ('cp1251', "Tatar", "Cyrillic"), + 0x041e : ('iso8859_11',"Thai", "Thai"), + 0x041f : ('iso8859_9', "Turkish", "Turkish"), + 0x0422 : ('cp1251', "Ukrainian", "Cyrillic"), + 0x0420 : ('iso8859_6', "Urdu", "Arabic"), + 0x0443 : ('iso8859_9', "Uzbek_Latin", "Turkish"), + 0x0843 : ('cp1251', "Uzbek_Cyrillic", "Cyrillic"), + 0x042a : (None, "Vietnamese", "Vietnamese") +} + +class CHMFile: + "A class to manage access to CHM files." + filename = "" + file = None + title = "" + home = "/" + index = None + topics = None + encoding = None + lcid = None + binaryindex = None + + def __init__(self): + self.searchable = 0 + + def LoadCHM(self, archiveName): + '''Loads a CHM archive. + This function will also call GetArchiveInfo to obtain information + such as the index file name and the topics file. It returns 1 on + success, and 0 if it fails. + ''' + if (self.filename != None): + self.CloseCHM() + + self.file = chmlib.chm_open(archiveName) + if (self.file == None): + return 0 + + self.filename = archiveName + self.GetArchiveInfo() + + return 1 + + def CloseCHM(self): + '''Closes the CHM archive. + This function will close the CHM file, if it is open. All variables + are also reset. + ''' + if (self.filename != None): + chmlib.chm_close(self.file) + self.file = None + self.filename = '' + self.title = "" + self.home = "/" + self.index = None + self.topics = None + self.encoding = None + + def GetArchiveInfo(self): + '''Obtains information on CHM archive. + This function checks the /#SYSTEM file inside the CHM archive to + obtain the index, home page, topics, encoding and title. It is called + from LoadCHM. + ''' + + #extra.is_searchable crashed... + #self.searchable = extra.is_searchable (self.file) + self.searchable = False + self.lcid = None + + result, ui = chmlib.chm_resolve_object(self.file, '/#SYSTEM') + if (result != chmlib.CHM_RESOLVE_SUCCESS): + sys.stderr.write('GetArchiveInfo: #SYSTEM does not exist\n') + return 0 + + size, text = chmlib.chm_retrieve_object(self.file, ui, 4l, ui.length) + if (size == 0): + sys.stderr.write('GetArchiveInfo: file size = 0\n') + return 0 + + buff = array.array('B', text) + + index = 0 + while (index < size): + cursor = buff[index] + (buff[index+1] * 256) + + if (cursor == 0): + index += 2 + cursor = buff[index] + (buff[index+1] * 256) + index += 2 + self.topics = '/' + text[index:index+cursor-1] + elif (cursor == 1): + index += 2 + cursor = buff[index] + (buff[index+1] * 256) + index += 2 + self.index = '/' + text[index:index+cursor-1] + elif (cursor == 2): + index += 2 + cursor = buff[index] + (buff[index+1] * 256) + index += 2 + self.home = '/' + text[index:index+cursor-1] + elif (cursor == 3): + index += 2 + cursor = buff[index] + (buff[index+1] * 256) + index += 2 + self.title = text[index:index+cursor-1] + elif (cursor == 4): + index += 2 + cursor = buff[index] + (buff[index+1] * 256) + index += 2 + self.lcid = buff[index] + (buff[index+1] * 256) + elif (cursor == 6): + index += 2 + cursor = buff[index] + (buff[index+1] * 256) + index += 2 + tmp = text[index:index+cursor-1] + if not self.topics: + tmp1 = '/' + tmp + '.hhc' + tmp2 = '/' + tmp + '.hhk' + res1, ui1 = chmlib.chm_resolve_object(self.file, tmp1) + res2, ui2 = chmlib.chm_resolve_object(self.file, tmp2) + if (not self.topics) and \ + (res1 == chmlib.CHM_RESOLVE_SUCCESS): + self.topics = '/' + tmp + '.hhc' + if (not self.index) and \ + (res2 == chmlib.CHM_RESOLVE_SUCCESS): + self.index = '/' + tmp + '.hhk' + elif (cursor == 16): + index += 2 + cursor = buff[index] + (buff[index+1] * 256) + index += 2 + self.encoding = text[index:index+cursor-1] + else: + index += 2 + cursor = buff[index] + (buff[index+1] * 256) + index += 2 + index += cursor + + self.GetWindowsInfo() + + if not self.lcid: + self.lcid = extra.get_lcid (self.file) + + return 1 + + def GetTopicsTree(self): + '''Reads and returns the topics tree. + This auxiliary function reads and returns the topics tree file + contents for the CHM archive. + ''' + if (self.topics == None): + return None + + if self.topics: + res, ui = chmlib.chm_resolve_object(self.file, self.topics) + if (res != chmlib.CHM_RESOLVE_SUCCESS): + return None + + size, text = chmlib.chm_retrieve_object(self.file, ui, 0l, ui.length) + if (size == 0): + sys.stderr.write('GetTopicsTree: file size = 0\n') + return None + return text + + def GetIndex(self): + '''Reads and returns the index tree. + This auxiliary function reads and returns the index tree file + contents for the CHM archive. + ''' + if (self.index == None): + return None + + if self.index: + res, ui = chmlib.chm_resolve_object(self.file, self.index) + if (res != chmlib.CHM_RESOLVE_SUCCESS): + return None + + size, text = chmlib.chm_retrieve_object(self.file, ui, 0l, ui.length) + if (size == 0): + sys.stderr.write('GetIndex: file size = 0\n') + return None + return text + + def ResolveObject(self, document): + '''Tries to locate a document in the archive. + This function tries to locate the document inside the archive. It + returns a tuple where the first element is zero if the function + was successful, and the second is the UnitInfo for that document. + The UnitInfo is used to retrieve the document contents + ''' + if self.file: + #path = os.path.abspath(document) + path = document + return chmlib.chm_resolve_object(self.file, path) + else: + return (1, None) + + def RetrieveObject(self, ui, start = -1, length = -1): + '''Retrieves the contents of a document. + This function takes a UnitInfo and two optional arguments, the first + being the start address and the second is the length. These define + the amount of data to be read from the archive. + ''' + if self.file and ui: + if length == -1: + len = ui.length + else: + len = length + if start == -1: + st = 0l + else: + st = long(start) + return chmlib.chm_retrieve_object(self.file, ui, st, len) + else: + return (0, '') + + def Search(self, text, wholewords=0, titleonly=0): + '''Performs full-text search on the archive. + The first parameter is the word to look for, the second + indicates if the search should be for whole words only, and + the third parameter indicates if the search should be + restricted to page titles. + This method will return a tuple, the first item + indicating if the search results were partial, and the second + item being a dictionary containing the results.''' + if text and text != '' and self.file: + return extra.search (self.file, text, wholewords, + titleonly) + else: + return None + + def IsSearchable(self): + '''Indicates if the full-text search is available for this + archive - this flag is updated when GetArchiveInfo is called''' + return self.searchable + + def GetEncoding(self): + '''Returns a string that can be used with the codecs python package + to encode or decode the files in the chm archive. If an error is + found, or if it is not possible to find the encoding, None is + returned.''' + if self.encoding: + vals = string.split(self.encoding, ',') + if len(vals) > 2: + try: + return charset_table[int(vals[2])] + except KeyError: + pass + return None + + def GetLCID(self): + '''Returns the archive Locale ID''' + if self.lcid in locale_table: + return locale_table[self.lcid] + else: + return None + + def GetDWORD(self, buff, idx=0): + '''Internal method. + Reads a double word (4 bytes) from a buffer. + ''' + result = buff[idx] + (buff[idx+1]<<8) + (buff[idx+2]<<16) + \ + (buff[idx+3]<<24) + + if result == 0xFFFFFFFF: + result = 0 + + return result + + def GetString(self, text, idx): + '''Internal method. + Retrieves a string from the #STRINGS buffer. + ''' + next = string.find(text, '\x00', idx) + chunk = text[idx:next] + return chunk + + def GetWindowsInfo(self): + '''Gets information from the #WINDOWS file. + Checks the #WINDOWS file to see if it has any info that was + not found in #SYSTEM (topics, index or default page. + ''' + result, ui = chmlib.chm_resolve_object(self.file, '/#WINDOWS') + if (result != chmlib.CHM_RESOLVE_SUCCESS): + return -1 + + size, text = chmlib.chm_retrieve_object(self.file, ui, 0l, 8) + if (size < 8): + return -2 + + buff = array.array('B', text) + num_entries = self.GetDWORD(buff, 0) + entry_size = self.GetDWORD(buff, 4) + + if num_entries < 1: + return -3 + + size, text = chmlib.chm_retrieve_object(self.file, ui, 8l, entry_size) + if (size < entry_size): + return -4 + + buff = array.array('B', text) + toc_index = self.GetDWORD(buff, 0x60) + idx_index = self.GetDWORD(buff, 0x64) + dft_index = self.GetDWORD(buff, 0x68) + + result, ui = chmlib.chm_resolve_object(self.file, '/#STRINGS') + if (result != chmlib.CHM_RESOLVE_SUCCESS): + return -5 + + size, text = chmlib.chm_retrieve_object(self.file, ui, 0l, ui.length) + if (size == 0): + return -6 + + if (not self.topics): + self.topics = self.GetString(text, toc_index) + if not self.topics.startswith("/"): + self.topics = "/" + self.topics + + if (not self.index): + self.index = self.GetString(text, idx_index) + if not self.index.startswith("/"): + self.index = "/" + self.index + + if (dft_index != 0): + self.home = self.GetString(text, dft_index) + if not self.home.startswith("/"): + self.home = "/" + self.home diff --git a/src/calibre/ebooks/chm/chm/chmlib.py b/src/calibre/ebooks/chm/chm/chmlib.py new file mode 100644 index 0000000000..98d3372b57 --- /dev/null +++ b/src/calibre/ebooks/chm/chm/chmlib.py @@ -0,0 +1,93 @@ +# This file was created automatically by SWIG. +# Don't modify this file, modify the SWIG interface instead. +# This file is compatible with both classic and new-style classes. +import _chmlib +def _swig_setattr(self,class_type,name,value): + if (name == "this"): + if isinstance(value, class_type): + self.__dict__[name] = value.this + if hasattr(value,"thisown"): self.__dict__["thisown"] = value.thisown + del value.thisown + return + method = class_type.__swig_setmethods__.get(name,None) + if method: return method(self,value) + self.__dict__[name] = value + +def _swig_getattr(self,class_type,name): + method = class_type.__swig_getmethods__.get(name,None) + if method: return method(self) + raise AttributeError,name + +import types +try: + _object = types.ObjectType + _newclass = 1 +except AttributeError: + class _object : pass + _newclass = 0 + + +CHM_UNCOMPRESSED = _chmlib.CHM_UNCOMPRESSED +CHM_COMPRESSED = _chmlib.CHM_COMPRESSED +CHM_MAX_PATHLEN = _chmlib.CHM_MAX_PATHLEN +class chmUnitInfo(_object): + __swig_setmethods__ = {} + __setattr__ = lambda self, name, value: _swig_setattr(self, chmUnitInfo, name, value) + __swig_getmethods__ = {} + __getattr__ = lambda self, name: _swig_getattr(self, chmUnitInfo, name) + __swig_setmethods__["start"] = _chmlib.chmUnitInfo_start_set + __swig_getmethods__["start"] = _chmlib.chmUnitInfo_start_get + if _newclass:start = property(_chmlib.chmUnitInfo_start_get,_chmlib.chmUnitInfo_start_set) + __swig_setmethods__["length"] = _chmlib.chmUnitInfo_length_set + __swig_getmethods__["length"] = _chmlib.chmUnitInfo_length_get + if _newclass:length = property(_chmlib.chmUnitInfo_length_get,_chmlib.chmUnitInfo_length_set) + __swig_setmethods__["space"] = _chmlib.chmUnitInfo_space_set + __swig_getmethods__["space"] = _chmlib.chmUnitInfo_space_get + if _newclass:space = property(_chmlib.chmUnitInfo_space_get,_chmlib.chmUnitInfo_space_set) + __swig_setmethods__["path"] = _chmlib.chmUnitInfo_path_set + __swig_getmethods__["path"] = _chmlib.chmUnitInfo_path_get + if _newclass:path = property(_chmlib.chmUnitInfo_path_get,_chmlib.chmUnitInfo_path_set) + def __init__(self,*args): + _swig_setattr(self, chmUnitInfo, 'this', apply(_chmlib.new_chmUnitInfo,args)) + _swig_setattr(self, chmUnitInfo, 'thisown', 1) + def __del__(self, destroy= _chmlib.delete_chmUnitInfo): + try: + if self.thisown: destroy(self) + except: pass + def __repr__(self): + return "" % (self.this,) + +class chmUnitInfoPtr(chmUnitInfo): + def __init__(self,this): + _swig_setattr(self, chmUnitInfo, 'this', this) + if not hasattr(self,"thisown"): _swig_setattr(self, chmUnitInfo, 'thisown', 0) + _swig_setattr(self, chmUnitInfo,self.__class__,chmUnitInfo) +_chmlib.chmUnitInfo_swigregister(chmUnitInfoPtr) + +chm_open = _chmlib.chm_open + +chm_close = _chmlib.chm_close + +CHM_PARAM_MAX_BLOCKS_CACHED = _chmlib.CHM_PARAM_MAX_BLOCKS_CACHED +chm_set_param = _chmlib.chm_set_param + +CHM_RESOLVE_SUCCESS = _chmlib.CHM_RESOLVE_SUCCESS +CHM_RESOLVE_FAILURE = _chmlib.CHM_RESOLVE_FAILURE +chm_resolve_object = _chmlib.chm_resolve_object + +chm_retrieve_object = _chmlib.chm_retrieve_object + +CHM_ENUMERATE_NORMAL = _chmlib.CHM_ENUMERATE_NORMAL +CHM_ENUMERATE_META = _chmlib.CHM_ENUMERATE_META +CHM_ENUMERATE_SPECIAL = _chmlib.CHM_ENUMERATE_SPECIAL +CHM_ENUMERATE_FILES = _chmlib.CHM_ENUMERATE_FILES +CHM_ENUMERATE_DIRS = _chmlib.CHM_ENUMERATE_DIRS +CHM_ENUMERATE_ALL = _chmlib.CHM_ENUMERATE_ALL +CHM_ENUMERATOR_FAILURE = _chmlib.CHM_ENUMERATOR_FAILURE +CHM_ENUMERATOR_CONTINUE = _chmlib.CHM_ENUMERATOR_CONTINUE +CHM_ENUMERATOR_SUCCESS = _chmlib.CHM_ENUMERATOR_SUCCESS +chm_enumerate = _chmlib.chm_enumerate + +chm_enumerate_dir = _chmlib.chm_enumerate_dir + + diff --git a/src/calibre/ebooks/chm/chm/extra.pyd b/src/calibre/ebooks/chm/chm/extra.pyd new file mode 100644 index 0000000000000000000000000000000000000000..fe5a58f23f2440d1aed638943822c29e5ddef36d GIT binary patch literal 57856 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 Y_~Y{<1%9N!j}-Wk0zXpVf0Y9N4-Y3&-2eap literal 0 HcmV?d00001 diff --git a/src/calibre/ebooks/chm/input.py b/src/calibre/ebooks/chm/input.py new file mode 100644 index 0000000000..8bb6f03aa7 --- /dev/null +++ b/src/calibre/ebooks/chm/input.py @@ -0,0 +1,348 @@ +from __future__ import with_statement +''' CHM File decoding support ''' +__license__ = 'GPL v3' +__copyright__ = '2008, Kovid Goyal ,' \ + ' and Alex Bramley .' + +import sys, logging, os, re, shutil, subprocess, uuid +from shutil import rmtree +from tempfile import mkdtemp +from mimetypes import guess_type as guess_mimetype +from htmlentitydefs import name2codepoint +from pprint import PrettyPrinter + +from BeautifulSoup import BeautifulSoup +from lxml import html, etree +from calibre.ebooks.chm.chm.chm import CHMFile +from calibre.ebooks.chm.chm.chmlib import ( + CHM_RESOLVE_SUCCESS, CHM_ENUMERATE_NORMAL, + chm_enumerate, chm_retrieve_object, +) + +from calibre.customize.conversion import InputFormatPlugin, OptionRecommendation +from calibre.utils.config import OptionParser +from calibre.ebooks.metadata import MetaInformation +from calibre.ebooks.metadata.opf2 import OPFCreator, Guide +from calibre.ebooks.metadata.toc import TOC +from calibre.ebooks.lrf.html.convert_from import process_file as html_process_file +from calibre.utils.localization import get_lang +from calibre.utils.filenames import ascii_filename + + +def match_string(s1, s2_already_lowered): + if s1 is not None and s2_already_lowered is not None: + if s1.lower()==s2_already_lowered: + return True + return False + +def option_parser(): + parser = OptionParser(usage=_('%prog [options] mybook.chm')) + parser.add_option('--output-dir', '-d', default='.', help=_('Output directory. Defaults to current directory'), dest='output') + parser.add_option('--verbose', default=False, action='store_true', dest='verbose') + parser.add_option("-t", "--title", action="store", type="string", \ + dest="title", help=_("Set the book title")) + parser.add_option('--title-sort', action='store', type='string', default=None, + dest='title_sort', help=_('Set sort key for the title')) + parser.add_option("-a", "--author", action="store", type="string", \ + dest="author", help=_("Set the author")) + parser.add_option('--author-sort', action='store', type='string', default=None, + dest='author_sort', help=_('Set sort key for the author')) + parser.add_option("-c", "--category", action="store", type="string", \ + dest="category", help=_("The category this book belongs" + " to. E.g.: History")) + parser.add_option("--thumbnail", action="store", type="string", \ + dest="thumbnail", help=_("Path to a graphic that will be" + " set as this files' thumbnail")) + parser.add_option("--comment", action="store", type="string", \ + dest="freetext", help=_("Path to a txt file containing a comment.")) + parser.add_option("--get-thumbnail", action="store_true", \ + dest="get_thumbnail", default=False, \ + help=_("Extract thumbnail from LRF file")) + parser.add_option('--publisher', default=None, help=_('Set the publisher')) + parser.add_option('--classification', default=None, help=_('Set the book classification')) + parser.add_option('--creator', default=None, help=_('Set the book creator')) + parser.add_option('--producer', default=None, help=_('Set the book producer')) + parser.add_option('--get-cover', action='store_true', default=False, + help=_('Extract cover from LRF file. Note that the LRF format has no defined cover, so we use some heuristics to guess the cover.')) + parser.add_option('--bookid', action='store', type='string', default=None, + dest='book_id', help=_('Set book ID')) + parser.add_option('--font-delta', action='store', type='int', default=0, + dest='font_delta', help=_('Set font delta')) + return parser + +class CHMError(Exception): + pass + +class CHMReader(CHMFile): + def __init__(self, input, log): + CHMFile.__init__(self) + if not self.LoadCHM(input): + raise CHMError("Unable to open CHM file '%s'"%(input,)) + self.log = log + self._sourcechm = input + self._contents = None + self._playorder = 0 + self._metadata = False + self._extracted = False + + # location of '.hhc' file, which is the CHM TOC. + self.root, ext = os.path.splitext(self.topics.lstrip('/')) + self.hhc_path = self.root + ".hhc" + + + def _parse_toc(self, ul, basedir=os.getcwdu()): + toc = TOC(play_order=self._playorder, base_path=basedir, text='') + self._playorder += 1 + for li in ul('li', recursive=False): + href = li.object('param', {'name': 'Local'})[0]['value'] + if href.count('#'): + href, frag = href.split('#') + else: + frag = None + name = self._deentity(li.object('param', {'name': 'Name'})[0]['value']) + #print "========>", name + toc.add_item(href, frag, name, play_order=self._playorder) + self._playorder += 1 + if li.ul: + child = self._parse_toc(li.ul) + child.parent = toc + toc.append(child) + #print toc + return toc + + + def GetFile(self, path): + # have to have abs paths for ResolveObject, but Contents() deliberately + # makes them relative. So we don't have to worry, re-add the leading /. + # note this path refers to the internal CHM structure + if path[0] != '/': + path = '/' + path + res, ui = self.ResolveObject(path) + if res != CHM_RESOLVE_SUCCESS: + raise CHMError("Unable to locate '%s' within CHM file '%s'"%(path, self.filename)) + size, data = self.RetrieveObject(ui) + if size == 0: + raise CHMError("'%s' is zero bytes in length!"%(path,)) + return data + + def ExtractFiles(self, output_dir=os.getcwdu()): + for path in self.Contents(): + lpath = os.path.join(output_dir, path) + self._ensure_dir(lpath) + data = self.GetFile(path) + with open(lpath, 'wb') as f: + if guess_mimetype(path)[0] == ('text/html'): + data = self._reformat(data) + f.write(data) + #subprocess.call(['extract_chmLib.exe', self._sourcechm, output_dir]) + self._extracted = True + + def _reformat(self, data): + try: + html = BeautifulSoup(data) + except UnicodeEncodeError: + # hit some strange encoding problems... + print "Unable to parse html for cleaning, leaving it :(" + return data + # nuke javascript... + [s.extract() for s in html('script')] + # remove forward and back nav bars from the top/bottom of each page + # cos they really fuck with the flow of things and generally waste space + # since we can't use [a,b] syntax to select arbitrary items from a list + # we'll have to do this manually... + t = html('table') + if t: + if (t[0].previousSibling is None + or t[0].previousSibling.previousSibling is None): + t[0].extract() + if (t[-1].nextSibling is None + or t[-1].nextSibling.nextSibling is None): + t[-1].extract() + # for some very odd reason each page's content appears to be in a table + # too. and this table has sub-tables for random asides... grr. + + # some images seem to be broken in some chm's :/ + for img in html('img'): + try: + # some are supposedly "relative"... lies. + while img['src'].startswith('../'): img['src'] = img['src'][3:] + # some have ";" at the end. + img['src'] = img['src'].split(';')[0] + except KeyError: + # and some don't even have a src= ?! + pass + # now give back some pretty html. + return html.prettify() + + def Contents(self): + if self._contents is not None: + return self._contents + paths = [] + def get_paths(chm, ui, ctx): + # skip directories + # note this path refers to the internal CHM structure + if ui.path[-1] != '/': + # and make paths relative + paths.append(ui.path.lstrip('/')) + chm_enumerate(self.file, CHM_ENUMERATE_NORMAL, get_paths, None) + self._contents = paths + return self._contents + + def _ensure_dir(self, path): + dir = os.path.dirname(path) + if not os.path.isdir(dir): + os.makedirs(dir) + + def extract_content(self, output_dir=os.getcwdu()): + self.ExtractFiles(output_dir=output_dir) + + +class CHMInput(InputFormatPlugin): + + name = 'CHM Input' + author = 'Kovid Goyal and Alex Bramley' + description = 'Convert CHM files to OEB' + file_types = set(['chm']) + + options = set([ + OptionRecommendation(name='dummy_option', recommended_value=False, + help=_('dummy option until real options are determined.')), + ]) + + def _chmtohtml(self, output_dir, chm_path, no_images, log): + log.debug('Opening CHM file') + rdr = CHMReader(chm_path, log) + log.debug('Extracting CHM to %s' % output_dir) + rdr.extract_content(output_dir) + return rdr.hhc_path + + + def convert(self, stream, options, file_ext, log, accelerators): + from calibre.ebooks.metadata.chm import get_metadata_ + + log.debug('Processing CHM...') + tdir = mkdtemp(prefix='chm2oeb_') + from calibre.customize.ui import plugin_for_input_format + html_input = plugin_for_input_format('html') + for opt in html_input.options: + setattr(options, opt.option.name, opt.recommended_value) + options.input_encoding = 'utf-8' + no_images = False #options.no_images + chm_name = stream.name + #chm_data = stream.read() + + #closing stream so CHM can be opened by external library + stream.close() + log.debug('tdir=%s' % tdir) + log.debug('stream.name=%s' % stream.name) + mainname = self._chmtohtml(tdir, chm_name, no_images, log) + mainpath = os.path.join(tdir, mainname) + + metadata = get_metadata_(tdir) + + cwd = os.getcwdu() + odi = options.debug_pipeline + options.debug_pipeline = None + # try a custom conversion: + oeb = self._create_oebbook(mainpath, tdir, options, log, metadata) + options.debug_pipeline = odi + #log.debug('DEBUG: Not removing tempdir %s' % tdir) + shutil.rmtree(tdir) + return oeb + + def _create_oebbook(self, hhcpath, basedir, opts, log, mi): + from calibre.ebooks.conversion.plumber import create_oebbook + from calibre.ebooks.oeb.base import DirContainer, \ + rewrite_links, urlnormalize, urldefrag, BINARY_MIME, OEB_STYLES, \ + xpath + from calibre import guess_type + import cssutils + oeb = create_oebbook(log, None, opts, self, + encoding=opts.input_encoding, populate=False) + self.oeb = oeb + + metadata = oeb.metadata + if mi.title: + metadata.add('title', mi.title) + if mi.authors: + for a in mi.authors: + metadata.add('creator', a, attrib={'role':'aut'}) + if mi.publisher: + metadata.add('publisher', mi.publisher) + if mi.isbn: + metadata.add('identifier', mi.isbn, attrib={'scheme':'ISBN'}) + if not metadata.language: + oeb.logger.warn(u'Language not specified') + metadata.add('language', get_lang()) + if not metadata.creator: + oeb.logger.warn('Creator not specified') + metadata.add('creator', self.oeb.translate(__('Unknown'))) + if not metadata.title: + oeb.logger.warn('Title not specified') + metadata.add('title', self.oeb.translate(__('Unknown'))) + + bookid = str(uuid.uuid4()) + metadata.add('identifier', bookid, id='uuid_id', scheme='uuid') + for ident in metadata.identifier: + if 'id' in ident.attrib: + self.oeb.uid = metadata.identifier[0] + break + + hhcdata = self._read_file(hhcpath) + hhcroot = html.fromstring(hhcdata) + chapters = self._process_nodes(hhcroot) + #print "=============================" + #print "Printing hhcroot" + #print etree.tostring(hhcroot, pretty_print=True) + #print "=============================" + log.debug('Found %d section nodes' % len(chapters)) + + if len(chapters) > 0: + path0 = chapters[0][1] + subpath = os.path.dirname(path0) + htmlpath = os.path.join(basedir, subpath) + + oeb.container = DirContainer(htmlpath, log) + for chapter in chapters: + title = chapter[0] + basename = os.path.basename(chapter[1]) + self._add_item(oeb, title, basename) + + oeb.container = DirContainer(htmlpath, oeb.log) + return oeb + + def _read_file(self, name): + f = open(name, 'rb') + data = f.read() + f.close() + return data + + def _visit_node(self, node, chapters): + # check that node is a normal node (not a comment, DOCTYPE, etc.) + # (normal nodes have string tags) + if isinstance(node.tag, basestring): + if match_string(node.tag, 'object') and match_string(node.attrib['type'], 'text/sitemap'): + for child in node: + if match_string(child.tag,'param') and match_string(child.attrib['name'], 'name'): + chapter_title = child.attrib['value'] + if match_string(child.tag,'param') and match_string(child.attrib['name'],'local'): + chapter_path = child.attrib['value'] + if chapter_title is not None and chapter_path is not None: + chapter = [chapter_title, chapter_path] + chapters.append(chapter) + + def _process_nodes(self, root): + chapters = [] + for node in root.iter(): + self._visit_node(node, chapters) + return chapters + + def _add_item(self, oeb, title, path): + bname = os.path.basename(path) + id, href = oeb.manifest.generate(id='html', + href=ascii_filename(bname)) + item = oeb.manifest.add(id, href, 'text/html') + item.html_input_href = bname + oeb.spine.add(item, True) + oeb.toc.add(title, item.href) + From a60e0ae66ad9670350606e49a3c1c098d96886e2 Mon Sep 17 00:00:00 2001 From: James Ralston <> Date: Mon, 8 Feb 2010 20:28:36 -0800 Subject: [PATCH 02/10] Original chm.py --- src/calibre/ebooks/chm/chm/chm.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/calibre/ebooks/chm/chm/chm.py b/src/calibre/ebooks/chm/chm/chm.py index bed89af944..4a55c6d7de 100644 --- a/src/calibre/ebooks/chm/chm/chm.py +++ b/src/calibre/ebooks/chm/chm/chm.py @@ -243,9 +243,7 @@ class CHMFile: from LoadCHM. ''' - #extra.is_searchable crashed... - #self.searchable = extra.is_searchable (self.file) - self.searchable = False + self.searchable = extra.is_searchable (self.file) self.lcid = None result, ui = chmlib.chm_resolve_object(self.file, '/#SYSTEM') @@ -369,8 +367,7 @@ class CHMFile: The UnitInfo is used to retrieve the document contents ''' if self.file: - #path = os.path.abspath(document) - path = document + path = os.path.abspath(document) return chmlib.chm_resolve_object(self.file, path) else: return (1, None) From 981a79ac344fa4b0d854293522211969a1351c70 Mon Sep 17 00:00:00 2001 From: James Ralston <> Date: Mon, 8 Feb 2010 20:35:28 -0800 Subject: [PATCH 03/10] Modified chm.py --- src/calibre/ebooks/chm/chm/chm.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/calibre/ebooks/chm/chm/chm.py b/src/calibre/ebooks/chm/chm/chm.py index 4a55c6d7de..bed89af944 100644 --- a/src/calibre/ebooks/chm/chm/chm.py +++ b/src/calibre/ebooks/chm/chm/chm.py @@ -243,7 +243,9 @@ class CHMFile: from LoadCHM. ''' - self.searchable = extra.is_searchable (self.file) + #extra.is_searchable crashed... + #self.searchable = extra.is_searchable (self.file) + self.searchable = False self.lcid = None result, ui = chmlib.chm_resolve_object(self.file, '/#SYSTEM') @@ -367,7 +369,8 @@ class CHMFile: The UnitInfo is used to retrieve the document contents ''' if self.file: - path = os.path.abspath(document) + #path = os.path.abspath(document) + path = document return chmlib.chm_resolve_object(self.file, path) else: return (1, None) From c84aa8105b4e28318a36bfb02f7a8529e50a42b8 Mon Sep 17 00:00:00 2001 From: James Ralston <> Date: Tue, 9 Feb 2010 00:04:36 -0800 Subject: [PATCH 04/10] Experiment with using html input plugin to process chm --- src/calibre/ebooks/chm/input.py | 55 ++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/src/calibre/ebooks/chm/input.py b/src/calibre/ebooks/chm/input.py index 8bb6f03aa7..c9116bcb5f 100644 --- a/src/calibre/ebooks/chm/input.py +++ b/src/calibre/ebooks/chm/input.py @@ -244,12 +244,24 @@ class CHMInput(InputFormatPlugin): odi = options.debug_pipeline options.debug_pipeline = None # try a custom conversion: - oeb = self._create_oebbook(mainpath, tdir, options, log, metadata) + #oeb = self._create_oebbook(mainpath, tdir, options, log, metadata) + # try using html converter: + htmlpath = self._create_html_root(mainpath, log) + oeb = self._create_oebbook_html(htmlpath, tdir, options, log, metadata) options.debug_pipeline = odi #log.debug('DEBUG: Not removing tempdir %s' % tdir) shutil.rmtree(tdir) return oeb + def _create_oebbook_html(self, htmlpath, basedir, opts, log, mi): + # use HTMLInput plugin to generate book + from calibre.ebooks.html.input import HTMLInput + opts.breadth_first = True + htmlinput = HTMLInput(None) + oeb = htmlinput.create_oebbook(htmlpath, basedir, opts, log, mi) + return oeb + + def _create_oebbook(self, hhcpath, basedir, opts, log, mi): from calibre.ebooks.conversion.plumber import create_oebbook from calibre.ebooks.oeb.base import DirContainer, \ @@ -311,13 +323,43 @@ class CHMInput(InputFormatPlugin): oeb.container = DirContainer(htmlpath, oeb.log) return oeb + def _create_html_root(self, hhcpath, log): + hhcdata = self._read_file(hhcpath) + hhcroot = html.fromstring(hhcdata) + chapters = self._process_nodes(hhcroot) + #print "=============================" + #print "Printing hhcroot" + #print etree.tostring(hhcroot, pretty_print=True) + #print "=============================" + log.debug('Found %d section nodes' % len(chapters)) + htmlpath = os.path.splitext(hhcpath)[0] + ".html" + f = open(htmlpath, 'wb') + f.write("\r\n") + + if chapters: + path0 = chapters[0][1] + subpath = os.path.dirname(path0) + + for chapter in chapters: + title = chapter[0] + rsrcname = os.path.basename(chapter[1]) + rsrcpath = os.path.join(subpath, rsrcname) + # title should already be url encoded + url = "
" + title + " \r\n" + f.write(url) + + f.write("") + f.close() + return htmlpath + + def _read_file(self, name): f = open(name, 'rb') data = f.read() f.close() return data - def _visit_node(self, node, chapters): + def _visit_node(self, node, chapters, depth): # check that node is a normal node (not a comment, DOCTYPE, etc.) # (normal nodes have string tags) if isinstance(node.tag, basestring): @@ -328,13 +370,18 @@ class CHMInput(InputFormatPlugin): if match_string(child.tag,'param') and match_string(child.attrib['name'],'local'): chapter_path = child.attrib['value'] if chapter_title is not None and chapter_path is not None: - chapter = [chapter_title, chapter_path] + chapter = [chapter_title, chapter_path, depth] chapters.append(chapter) + if node.tag=="UL": + depth = depth + 1 + if node.tag=="/UL": + depth = depth - 1 def _process_nodes(self, root): chapters = [] + depth = 0 for node in root.iter(): - self._visit_node(node, chapters) + self._visit_node(node, chapters, depth) return chapters def _add_item(self, oeb, title, path): From f488c667408add4e949d665540411b96c33a421b Mon Sep 17 00:00:00 2001 From: James Ralston <> Date: Tue, 9 Feb 2010 23:37:56 -0800 Subject: [PATCH 05/10] Move pychm to src --- src/calibre/ebooks/chm/chm/__init__.py | 34 -- src/calibre/ebooks/chm/chm/_chmlib.pyd | Bin 92672 -> 0 bytes src/calibre/ebooks/chm/chm/chm.py | 508 ------------------------- src/calibre/ebooks/chm/chm/chmlib.py | 93 ----- src/calibre/ebooks/chm/chm/extra.pyd | Bin 57856 -> 0 bytes src/calibre/ebooks/chm/input.py | 4 +- 6 files changed, 2 insertions(+), 637 deletions(-) delete mode 100644 src/calibre/ebooks/chm/chm/__init__.py delete mode 100644 src/calibre/ebooks/chm/chm/_chmlib.pyd delete mode 100644 src/calibre/ebooks/chm/chm/chm.py delete mode 100644 src/calibre/ebooks/chm/chm/chmlib.py delete mode 100644 src/calibre/ebooks/chm/chm/extra.pyd diff --git a/src/calibre/ebooks/chm/chm/__init__.py b/src/calibre/ebooks/chm/chm/__init__.py deleted file mode 100644 index 83fcb5c50e..0000000000 --- a/src/calibre/ebooks/chm/chm/__init__.py +++ /dev/null @@ -1,34 +0,0 @@ -## Copyright (C) 2003-2006 Rubens Ramos - -## pychm is free software; you can redistribute it and/or -## modify it under the terms of the GNU General Public License as -## published by the Free Software Foundation; either version 2 of the -## License, or (at your option) any later version. - -## This program 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. See the GNU -## General Public License for more details. - -## You should have received a copy of the GNU General Public -## License along with this program; see the file COPYING. If not, -## write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -## Boston, MA 02111-1307, USA - -## $Id: __init__.py,v 1.8 2006/06/18 10:50:43 rubensr Exp $ - -''' - chm - A package to manipulate CHM files - - The chm package provides four modules: chm, chmlib, extra and - _chmlib. _chmlib and chmlib are very low level libraries generated - from SWIG interface files, and are simple wrappers around the API - defined by the C library chmlib. - The extra module adds full-text search support. - the chm module provides some higher level classes to simplify - access to the CHM files information. -''' -__all__ = ["chm", "chmlib", "_chmlib", "extra"] -__version__ = "0.8.4" -__revision__ = "$Id: __init__.py,v 1.8 2006/06/18 10:50:43 rubensr Exp $" - diff --git a/src/calibre/ebooks/chm/chm/_chmlib.pyd b/src/calibre/ebooks/chm/chm/_chmlib.pyd deleted file mode 100644 index ef963bf87383906ead8118be45e1441506556f97..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 92672 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 - -## Based on code by: -## Copyright (C) 2003 Razvan Cojocaru - -## pychm is free software; you can redistribute it and/or -## modify it under the terms of the GNU General Public License as -## published by the Free Software Foundation; either version 2 of the -## License, or (at your option) any later version. - -## This program 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. See the GNU -## General Public License for more details. - -## You should have received a copy of the GNU General Public -## License along with this program; see the file COPYING. If not, -## write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -## Boston, MA 02111-1307, USA - -## $Id: chm.py,v 1.12 2006/08/07 12:31:51 rubensr Exp $ - -''' - chm - A high-level front end for the chmlib python module. - - The chm module provides high level access to the functionality - included in chmlib. It encapsulates functions in the CHMFile class, and - provides some additional features, such as the ability to obtain - the contents tree of a CHM archive. - -''' - -import chmlib -import extra -import array -import string -import os.path -import sys - -charset_table = { - 0 : 'iso8859_1', # ANSI_CHARSET - 238 : 'iso8859_2', # EASTEUROPE_CHARSET - 178 : 'iso8859_6', # ARABIC_CHARSET - 161 : 'iso8859_7', # GREEK_CHARSET - 177 : 'iso8859_8', # HEBREW_CHARSET - 162 : 'iso8859_9', # TURKISH_CHARSET - 222 : 'iso8859_11', # THAI_CHARSET - hmm not in python 2.2... - 186 : 'iso8859_13', # BALTIC_CHARSET - 204 : 'cp1251', # RUSSIAN_CHARSET - 255 : 'cp437', # OEM_CHARSET - 128 : 'cp932', # SHIFTJIS_CHARSET - 134 : 'cp936', # GB2312_CHARSET - 129 : 'cp949', # HANGUL_CHARSET - 136 : 'cp950', # CHINESEBIG5_CHARSET - 1 : None, # DEFAULT_CHARSET - 2 : None, # SYMBOL_CHARSET - 130 : None, # JOHAB_CHARSET - 163 : None, # VIETNAMESE_CHARSET - 77 : None, # MAC_CHARSET -} - -locale_table = { - 0x0436 : ('iso8859_1', "Afrikaans", "Western Europe & US"), - 0x041c : ('iso8859_2', "Albanian", "Central Europe"), - 0x0401 : ('iso8859_6', "Arabic_Saudi_Arabia", "Arabic"), - 0x0801 : ('iso8859_6', "Arabic_Iraq", "Arabic"), - 0x0c01 : ('iso8859_6', "Arabic_Egypt", "Arabic"), - 0x1001 : ('iso8859_6', "Arabic_Libya", "Arabic"), - 0x1401 : ('iso8859_6', "Arabic_Algeria", "Arabic"), - 0x1801 : ('iso8859_6', "Arabic_Morocco", "Arabic"), - 0x1c01 : ('iso8859_6', "Arabic_Tunisia", "Arabic"), - 0x2001 : ('iso8859_6', "Arabic_Oman", "Arabic"), - 0x2401 : ('iso8859_6', "Arabic_Yemen", "Arabic"), - 0x2801 : ('iso8859_6', "Arabic_Syria", "Arabic"), - 0x2c01 : ('iso8859_6', "Arabic_Jordan", "Arabic"), - 0x3001 : ('iso8859_6', "Arabic_Lebanon", "Arabic"), - 0x3401 : ('iso8859_6', "Arabic_Kuwait", "Arabic"), - 0x3801 : ('iso8859_6', "Arabic_UAE", "Arabic"), - 0x3c01 : ('iso8859_6', "Arabic_Bahrain", "Arabic"), - 0x4001 : ('iso8859_6', "Arabic_Qatar", "Arabic"), - 0x042b : (None, "Armenian","Armenian"), - 0x042c : ('iso8859_9', "Azeri_Latin", "Turkish"), - 0x082c : ('cp1251', "Azeri_Cyrillic", "Cyrillic"), - 0x042d : ('iso8859_1', "Basque", "Western Europe & US"), - 0x0423 : ('cp1251', "Belarusian", "Cyrillic"), - 0x0402 : ('cp1251', "Bulgarian", "Cyrillic"), - 0x0403 : ('iso8859_1', "Catalan", "Western Europe & US"), - 0x0404 : ('cp950', "Chinese_Taiwan", "Traditional Chinese"), - 0x0804 : ('cp936', "Chinese_PRC", "Simplified Chinese"), - 0x0c04 : ('cp950', "Chinese_Hong_Kong", "Traditional Chinese"), - 0x1004 : ('cp936', "Chinese_Singapore", "Simplified Chinese"), - 0x1404 : ('cp950', "Chinese_Macau", "Traditional Chinese"), - 0x041a : ('iso8859_2', "Croatian", "Central Europe"), - 0x0405 : ('iso8859_2', "Czech", "Central Europe"), - 0x0406 : ('iso8859_1', "Danish", "Western Europe & US"), - 0x0413 : ('iso8859_1', "Dutch_Standard", "Western Europe & US"), - 0x0813 : ('iso8859_1', "Dutch_Belgian", "Western Europe & US"), - 0x0409 : ('iso8859_1', "English_United_States", "Western Europe & US"), - 0x0809 : ('iso8859_1', "English_United_Kingdom", "Western Europe & US"), - 0x0c09 : ('iso8859_1', "English_Australian", "Western Europe & US"), - 0x1009 : ('iso8859_1', "English_Canadian", "Western Europe & US"), - 0x1409 : ('iso8859_1', "English_New_Zealand", "Western Europe & US"), - 0x1809 : ('iso8859_1', "English_Irish", "Western Europe & US"), - 0x1c09 : ('iso8859_1', "English_South_Africa", "Western Europe & US"), - 0x2009 : ('iso8859_1', "English_Jamaica", "Western Europe & US"), - 0x2409 : ('iso8859_1', "English_Caribbean", "Western Europe & US"), - 0x2809 : ('iso8859_1', "English_Belize", "Western Europe & US"), - 0x2c09 : ('iso8859_1', "English_Trinidad", "Western Europe & US"), - 0x3009 : ('iso8859_1', "English_Zimbabwe", "Western Europe & US"), - 0x3409 : ('iso8859_1', "English_Philippines", "Western Europe & US"), - 0x0425 : ('iso8859_13',"Estonian", "Baltic",), - 0x0438 : ('iso8859_1', "Faeroese", "Western Europe & US"), - 0x0429 : ('iso8859_6', "Farsi", "Arabic"), - 0x040b : ('iso8859_1', "Finnish", "Western Europe & US"), - 0x040c : ('iso8859_1', "French_Standard", "Western Europe & US"), - 0x080c : ('iso8859_1', "French_Belgian", "Western Europe & US"), - 0x0c0c : ('iso8859_1', "French_Canadian", "Western Europe & US"), - 0x100c : ('iso8859_1', "French_Swiss", "Western Europe & US"), - 0x140c : ('iso8859_1', "French_Luxembourg", "Western Europe & US"), - 0x180c : ('iso8859_1', "French_Monaco", "Western Europe & US"), - 0x0437 : (None, "Georgian", "Georgian"), - 0x0407 : ('iso8859_1', "German_Standard", "Western Europe & US"), - 0x0807 : ('iso8859_1', "German_Swiss", "Western Europe & US"), - 0x0c07 : ('iso8859_1', "German_Austrian", "Western Europe & US"), - 0x1007 : ('iso8859_1', "German_Luxembourg", "Western Europe & US"), - 0x1407 : ('iso8859_1', "German_Liechtenstein", "Western Europe & US"), - 0x0408 : ('iso8859_7', "Greek", "Greek"), - 0x040d : ('iso8859_8', "Hebrew", "Hebrew"), - 0x0439 : (None, "Hindi", "Indic"), - 0x040e : ('iso8859_2', "Hungarian", "Central Europe"), - 0x040f : ('iso8859_1', "Icelandic", "Western Europe & US"), - 0x0421 : ('iso8859_1', "Indonesian", "Western Europe & US"), - 0x0410 : ('iso8859_1', "Italian_Standard", "Western Europe & US"), - 0x0810 : ('iso8859_1', "Italian_Swiss", "Western Europe & US"), - 0x0411 : ('cp932', "Japanese", "Japanese"), - 0x043f : ('cp1251', "Kazakh", "Cyrillic"), - 0x0457 : (None, "Konkani", "Indic"), - 0x0412 : ('cp949', "Korean", "Korean"), - 0x0426 : ('iso8859_13',"Latvian", "Baltic",), - 0x0427 : ('iso8859_13',"Lithuanian", "Baltic",), - 0x042f : ('cp1251', "Macedonian", "Cyrillic"), - 0x043e : ('iso8859_1', "Malay_Malaysia", "Western Europe & US"), - 0x083e : ('iso8859_1', "Malay_Brunei_Darussalam", "Western Europe & US"), - 0x044e : (None, "Marathi", "Indic"), - 0x0414 : ('iso8859_1', "Norwegian_Bokmal", "Western Europe & US"), - 0x0814 : ('iso8859_1', "Norwegian_Nynorsk", "Western Europe & US"), - 0x0415 : ('iso8859_2', "Polish", "Central Europe"), - 0x0416 : ('iso8859_1', "Portuguese_Brazilian", "Western Europe & US"), - 0x0816 : ('iso8859_1', "Portuguese_Standard", "Western Europe & US"), - 0x0418 : ('iso8859_2', "Romanian", "Central Europe"), - 0x0419 : ('cp1251', "Russian", "Cyrillic"), - 0x044f : (None, "Sanskrit", "Indic"), - 0x081a : ('iso8859_2', "Serbian_Latin", "Central Europe"), - 0x0c1a : ('cp1251', "Serbian_Cyrillic", "Cyrillic"), - 0x041b : ('iso8859_2', "Slovak", "Central Europe"), - 0x0424 : ('iso8859_2', "Slovenian", "Central Europe"), - 0x040a : ('iso8859_1', "Spanish_Trad_Sort", "Western Europe & US"), - 0x080a : ('iso8859_1', "Spanish_Mexican", "Western Europe & US"), - 0x0c0a : ('iso8859_1', "Spanish_Modern_Sort", "Western Europe & US"), - 0x100a : ('iso8859_1', "Spanish_Guatemala", "Western Europe & US"), - 0x140a : ('iso8859_1', "Spanish_Costa_Rica", "Western Europe & US"), - 0x180a : ('iso8859_1', "Spanish_Panama", "Western Europe & US"), - 0x1c0a : ('iso8859_1', "Spanish_Dominican_Repub", "Western Europe & US"), - 0x200a : ('iso8859_1', "Spanish_Venezuela", "Western Europe & US"), - 0x240a : ('iso8859_1', "Spanish_Colombia", "Western Europe & US"), - 0x280a : ('iso8859_1', "Spanish_Peru", "Western Europe & US"), - 0x2c0a : ('iso8859_1', "Spanish_Argentina", "Western Europe & US"), - 0x300a : ('iso8859_1', "Spanish_Ecuador", "Western Europe & US"), - 0x340a : ('iso8859_1', "Spanish_Chile", "Western Europe & US"), - 0x380a : ('iso8859_1', "Spanish_Uruguay", "Western Europe & US"), - 0x3c0a : ('iso8859_1', "Spanish_Paraguay", "Western Europe & US"), - 0x400a : ('iso8859_1', "Spanish_Bolivia", "Western Europe & US"), - 0x440a : ('iso8859_1', "Spanish_El_Salvador", "Western Europe & US"), - 0x480a : ('iso8859_1', "Spanish_Honduras", "Western Europe & US"), - 0x4c0a : ('iso8859_1', "Spanish_Nicaragua", "Western Europe & US"), - 0x500a : ('iso8859_1', "Spanish_Puerto_Rico", "Western Europe & US"), - 0x0441 : ('iso8859_1', "Swahili", "Western Europe & US"), - 0x041d : ('iso8859_1', "Swedish", "Western Europe & US"), - 0x081d : ('iso8859_1', "Swedish_Finland", "Western Europe & US"), - 0x0449 : (None, "Tamil", "Indic"), - 0x0444 : ('cp1251', "Tatar", "Cyrillic"), - 0x041e : ('iso8859_11',"Thai", "Thai"), - 0x041f : ('iso8859_9', "Turkish", "Turkish"), - 0x0422 : ('cp1251', "Ukrainian", "Cyrillic"), - 0x0420 : ('iso8859_6', "Urdu", "Arabic"), - 0x0443 : ('iso8859_9', "Uzbek_Latin", "Turkish"), - 0x0843 : ('cp1251', "Uzbek_Cyrillic", "Cyrillic"), - 0x042a : (None, "Vietnamese", "Vietnamese") -} - -class CHMFile: - "A class to manage access to CHM files." - filename = "" - file = None - title = "" - home = "/" - index = None - topics = None - encoding = None - lcid = None - binaryindex = None - - def __init__(self): - self.searchable = 0 - - def LoadCHM(self, archiveName): - '''Loads a CHM archive. - This function will also call GetArchiveInfo to obtain information - such as the index file name and the topics file. It returns 1 on - success, and 0 if it fails. - ''' - if (self.filename != None): - self.CloseCHM() - - self.file = chmlib.chm_open(archiveName) - if (self.file == None): - return 0 - - self.filename = archiveName - self.GetArchiveInfo() - - return 1 - - def CloseCHM(self): - '''Closes the CHM archive. - This function will close the CHM file, if it is open. All variables - are also reset. - ''' - if (self.filename != None): - chmlib.chm_close(self.file) - self.file = None - self.filename = '' - self.title = "" - self.home = "/" - self.index = None - self.topics = None - self.encoding = None - - def GetArchiveInfo(self): - '''Obtains information on CHM archive. - This function checks the /#SYSTEM file inside the CHM archive to - obtain the index, home page, topics, encoding and title. It is called - from LoadCHM. - ''' - - #extra.is_searchable crashed... - #self.searchable = extra.is_searchable (self.file) - self.searchable = False - self.lcid = None - - result, ui = chmlib.chm_resolve_object(self.file, '/#SYSTEM') - if (result != chmlib.CHM_RESOLVE_SUCCESS): - sys.stderr.write('GetArchiveInfo: #SYSTEM does not exist\n') - return 0 - - size, text = chmlib.chm_retrieve_object(self.file, ui, 4l, ui.length) - if (size == 0): - sys.stderr.write('GetArchiveInfo: file size = 0\n') - return 0 - - buff = array.array('B', text) - - index = 0 - while (index < size): - cursor = buff[index] + (buff[index+1] * 256) - - if (cursor == 0): - index += 2 - cursor = buff[index] + (buff[index+1] * 256) - index += 2 - self.topics = '/' + text[index:index+cursor-1] - elif (cursor == 1): - index += 2 - cursor = buff[index] + (buff[index+1] * 256) - index += 2 - self.index = '/' + text[index:index+cursor-1] - elif (cursor == 2): - index += 2 - cursor = buff[index] + (buff[index+1] * 256) - index += 2 - self.home = '/' + text[index:index+cursor-1] - elif (cursor == 3): - index += 2 - cursor = buff[index] + (buff[index+1] * 256) - index += 2 - self.title = text[index:index+cursor-1] - elif (cursor == 4): - index += 2 - cursor = buff[index] + (buff[index+1] * 256) - index += 2 - self.lcid = buff[index] + (buff[index+1] * 256) - elif (cursor == 6): - index += 2 - cursor = buff[index] + (buff[index+1] * 256) - index += 2 - tmp = text[index:index+cursor-1] - if not self.topics: - tmp1 = '/' + tmp + '.hhc' - tmp2 = '/' + tmp + '.hhk' - res1, ui1 = chmlib.chm_resolve_object(self.file, tmp1) - res2, ui2 = chmlib.chm_resolve_object(self.file, tmp2) - if (not self.topics) and \ - (res1 == chmlib.CHM_RESOLVE_SUCCESS): - self.topics = '/' + tmp + '.hhc' - if (not self.index) and \ - (res2 == chmlib.CHM_RESOLVE_SUCCESS): - self.index = '/' + tmp + '.hhk' - elif (cursor == 16): - index += 2 - cursor = buff[index] + (buff[index+1] * 256) - index += 2 - self.encoding = text[index:index+cursor-1] - else: - index += 2 - cursor = buff[index] + (buff[index+1] * 256) - index += 2 - index += cursor - - self.GetWindowsInfo() - - if not self.lcid: - self.lcid = extra.get_lcid (self.file) - - return 1 - - def GetTopicsTree(self): - '''Reads and returns the topics tree. - This auxiliary function reads and returns the topics tree file - contents for the CHM archive. - ''' - if (self.topics == None): - return None - - if self.topics: - res, ui = chmlib.chm_resolve_object(self.file, self.topics) - if (res != chmlib.CHM_RESOLVE_SUCCESS): - return None - - size, text = chmlib.chm_retrieve_object(self.file, ui, 0l, ui.length) - if (size == 0): - sys.stderr.write('GetTopicsTree: file size = 0\n') - return None - return text - - def GetIndex(self): - '''Reads and returns the index tree. - This auxiliary function reads and returns the index tree file - contents for the CHM archive. - ''' - if (self.index == None): - return None - - if self.index: - res, ui = chmlib.chm_resolve_object(self.file, self.index) - if (res != chmlib.CHM_RESOLVE_SUCCESS): - return None - - size, text = chmlib.chm_retrieve_object(self.file, ui, 0l, ui.length) - if (size == 0): - sys.stderr.write('GetIndex: file size = 0\n') - return None - return text - - def ResolveObject(self, document): - '''Tries to locate a document in the archive. - This function tries to locate the document inside the archive. It - returns a tuple where the first element is zero if the function - was successful, and the second is the UnitInfo for that document. - The UnitInfo is used to retrieve the document contents - ''' - if self.file: - #path = os.path.abspath(document) - path = document - return chmlib.chm_resolve_object(self.file, path) - else: - return (1, None) - - def RetrieveObject(self, ui, start = -1, length = -1): - '''Retrieves the contents of a document. - This function takes a UnitInfo and two optional arguments, the first - being the start address and the second is the length. These define - the amount of data to be read from the archive. - ''' - if self.file and ui: - if length == -1: - len = ui.length - else: - len = length - if start == -1: - st = 0l - else: - st = long(start) - return chmlib.chm_retrieve_object(self.file, ui, st, len) - else: - return (0, '') - - def Search(self, text, wholewords=0, titleonly=0): - '''Performs full-text search on the archive. - The first parameter is the word to look for, the second - indicates if the search should be for whole words only, and - the third parameter indicates if the search should be - restricted to page titles. - This method will return a tuple, the first item - indicating if the search results were partial, and the second - item being a dictionary containing the results.''' - if text and text != '' and self.file: - return extra.search (self.file, text, wholewords, - titleonly) - else: - return None - - def IsSearchable(self): - '''Indicates if the full-text search is available for this - archive - this flag is updated when GetArchiveInfo is called''' - return self.searchable - - def GetEncoding(self): - '''Returns a string that can be used with the codecs python package - to encode or decode the files in the chm archive. If an error is - found, or if it is not possible to find the encoding, None is - returned.''' - if self.encoding: - vals = string.split(self.encoding, ',') - if len(vals) > 2: - try: - return charset_table[int(vals[2])] - except KeyError: - pass - return None - - def GetLCID(self): - '''Returns the archive Locale ID''' - if self.lcid in locale_table: - return locale_table[self.lcid] - else: - return None - - def GetDWORD(self, buff, idx=0): - '''Internal method. - Reads a double word (4 bytes) from a buffer. - ''' - result = buff[idx] + (buff[idx+1]<<8) + (buff[idx+2]<<16) + \ - (buff[idx+3]<<24) - - if result == 0xFFFFFFFF: - result = 0 - - return result - - def GetString(self, text, idx): - '''Internal method. - Retrieves a string from the #STRINGS buffer. - ''' - next = string.find(text, '\x00', idx) - chunk = text[idx:next] - return chunk - - def GetWindowsInfo(self): - '''Gets information from the #WINDOWS file. - Checks the #WINDOWS file to see if it has any info that was - not found in #SYSTEM (topics, index or default page. - ''' - result, ui = chmlib.chm_resolve_object(self.file, '/#WINDOWS') - if (result != chmlib.CHM_RESOLVE_SUCCESS): - return -1 - - size, text = chmlib.chm_retrieve_object(self.file, ui, 0l, 8) - if (size < 8): - return -2 - - buff = array.array('B', text) - num_entries = self.GetDWORD(buff, 0) - entry_size = self.GetDWORD(buff, 4) - - if num_entries < 1: - return -3 - - size, text = chmlib.chm_retrieve_object(self.file, ui, 8l, entry_size) - if (size < entry_size): - return -4 - - buff = array.array('B', text) - toc_index = self.GetDWORD(buff, 0x60) - idx_index = self.GetDWORD(buff, 0x64) - dft_index = self.GetDWORD(buff, 0x68) - - result, ui = chmlib.chm_resolve_object(self.file, '/#STRINGS') - if (result != chmlib.CHM_RESOLVE_SUCCESS): - return -5 - - size, text = chmlib.chm_retrieve_object(self.file, ui, 0l, ui.length) - if (size == 0): - return -6 - - if (not self.topics): - self.topics = self.GetString(text, toc_index) - if not self.topics.startswith("/"): - self.topics = "/" + self.topics - - if (not self.index): - self.index = self.GetString(text, idx_index) - if not self.index.startswith("/"): - self.index = "/" + self.index - - if (dft_index != 0): - self.home = self.GetString(text, dft_index) - if not self.home.startswith("/"): - self.home = "/" + self.home diff --git a/src/calibre/ebooks/chm/chm/chmlib.py b/src/calibre/ebooks/chm/chm/chmlib.py deleted file mode 100644 index 98d3372b57..0000000000 --- a/src/calibre/ebooks/chm/chm/chmlib.py +++ /dev/null @@ -1,93 +0,0 @@ -# This file was created automatically by SWIG. -# Don't modify this file, modify the SWIG interface instead. -# This file is compatible with both classic and new-style classes. -import _chmlib -def _swig_setattr(self,class_type,name,value): - if (name == "this"): - if isinstance(value, class_type): - self.__dict__[name] = value.this - if hasattr(value,"thisown"): self.__dict__["thisown"] = value.thisown - del value.thisown - return - method = class_type.__swig_setmethods__.get(name,None) - if method: return method(self,value) - self.__dict__[name] = value - -def _swig_getattr(self,class_type,name): - method = class_type.__swig_getmethods__.get(name,None) - if method: return method(self) - raise AttributeError,name - -import types -try: - _object = types.ObjectType - _newclass = 1 -except AttributeError: - class _object : pass - _newclass = 0 - - -CHM_UNCOMPRESSED = _chmlib.CHM_UNCOMPRESSED -CHM_COMPRESSED = _chmlib.CHM_COMPRESSED -CHM_MAX_PATHLEN = _chmlib.CHM_MAX_PATHLEN -class chmUnitInfo(_object): - __swig_setmethods__ = {} - __setattr__ = lambda self, name, value: _swig_setattr(self, chmUnitInfo, name, value) - __swig_getmethods__ = {} - __getattr__ = lambda self, name: _swig_getattr(self, chmUnitInfo, name) - __swig_setmethods__["start"] = _chmlib.chmUnitInfo_start_set - __swig_getmethods__["start"] = _chmlib.chmUnitInfo_start_get - if _newclass:start = property(_chmlib.chmUnitInfo_start_get,_chmlib.chmUnitInfo_start_set) - __swig_setmethods__["length"] = _chmlib.chmUnitInfo_length_set - __swig_getmethods__["length"] = _chmlib.chmUnitInfo_length_get - if _newclass:length = property(_chmlib.chmUnitInfo_length_get,_chmlib.chmUnitInfo_length_set) - __swig_setmethods__["space"] = _chmlib.chmUnitInfo_space_set - __swig_getmethods__["space"] = _chmlib.chmUnitInfo_space_get - if _newclass:space = property(_chmlib.chmUnitInfo_space_get,_chmlib.chmUnitInfo_space_set) - __swig_setmethods__["path"] = _chmlib.chmUnitInfo_path_set - __swig_getmethods__["path"] = _chmlib.chmUnitInfo_path_get - if _newclass:path = property(_chmlib.chmUnitInfo_path_get,_chmlib.chmUnitInfo_path_set) - def __init__(self,*args): - _swig_setattr(self, chmUnitInfo, 'this', apply(_chmlib.new_chmUnitInfo,args)) - _swig_setattr(self, chmUnitInfo, 'thisown', 1) - def __del__(self, destroy= _chmlib.delete_chmUnitInfo): - try: - if self.thisown: destroy(self) - except: pass - def __repr__(self): - return "" % (self.this,) - -class chmUnitInfoPtr(chmUnitInfo): - def __init__(self,this): - _swig_setattr(self, chmUnitInfo, 'this', this) - if not hasattr(self,"thisown"): _swig_setattr(self, chmUnitInfo, 'thisown', 0) - _swig_setattr(self, chmUnitInfo,self.__class__,chmUnitInfo) -_chmlib.chmUnitInfo_swigregister(chmUnitInfoPtr) - -chm_open = _chmlib.chm_open - -chm_close = _chmlib.chm_close - -CHM_PARAM_MAX_BLOCKS_CACHED = _chmlib.CHM_PARAM_MAX_BLOCKS_CACHED -chm_set_param = _chmlib.chm_set_param - -CHM_RESOLVE_SUCCESS = _chmlib.CHM_RESOLVE_SUCCESS -CHM_RESOLVE_FAILURE = _chmlib.CHM_RESOLVE_FAILURE -chm_resolve_object = _chmlib.chm_resolve_object - -chm_retrieve_object = _chmlib.chm_retrieve_object - -CHM_ENUMERATE_NORMAL = _chmlib.CHM_ENUMERATE_NORMAL -CHM_ENUMERATE_META = _chmlib.CHM_ENUMERATE_META -CHM_ENUMERATE_SPECIAL = _chmlib.CHM_ENUMERATE_SPECIAL -CHM_ENUMERATE_FILES = _chmlib.CHM_ENUMERATE_FILES -CHM_ENUMERATE_DIRS = _chmlib.CHM_ENUMERATE_DIRS -CHM_ENUMERATE_ALL = _chmlib.CHM_ENUMERATE_ALL -CHM_ENUMERATOR_FAILURE = _chmlib.CHM_ENUMERATOR_FAILURE -CHM_ENUMERATOR_CONTINUE = _chmlib.CHM_ENUMERATOR_CONTINUE -CHM_ENUMERATOR_SUCCESS = _chmlib.CHM_ENUMERATOR_SUCCESS -chm_enumerate = _chmlib.chm_enumerate - -chm_enumerate_dir = _chmlib.chm_enumerate_dir - - diff --git a/src/calibre/ebooks/chm/chm/extra.pyd b/src/calibre/ebooks/chm/chm/extra.pyd deleted file mode 100644 index fe5a58f23f2440d1aed638943822c29e5ddef36d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57856 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 Y_~Y{<1%9N!j}-Wk0zXpVf0Y9N4-Y3&-2eap diff --git a/src/calibre/ebooks/chm/input.py b/src/calibre/ebooks/chm/input.py index c9116bcb5f..a2976c944a 100644 --- a/src/calibre/ebooks/chm/input.py +++ b/src/calibre/ebooks/chm/input.py @@ -13,8 +13,8 @@ from pprint import PrettyPrinter from BeautifulSoup import BeautifulSoup from lxml import html, etree -from calibre.ebooks.chm.chm.chm import CHMFile -from calibre.ebooks.chm.chm.chmlib import ( +from pychm.chm import CHMFile +from pychm.chmlib import ( CHM_RESOLVE_SUCCESS, CHM_ENUMERATE_NORMAL, chm_enumerate, chm_retrieve_object, ) From 108c53e1942d9a1f1bc873123eb9d88b104201d2 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 16 Feb 2010 17:44:17 -0700 Subject: [PATCH 06/10] Katherimini and Ta Nea by Pan --- resources/kathemerini.recipe | 37 ++++++++++++++++++++++++++++++++++++ resources/tanea.recipe | 30 +++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 resources/kathemerini.recipe create mode 100644 resources/tanea.recipe diff --git a/resources/kathemerini.recipe b/resources/kathemerini.recipe new file mode 100644 index 0000000000..b68a35d0a8 --- /dev/null +++ b/resources/kathemerini.recipe @@ -0,0 +1,37 @@ +from calibre.web.feeds.recipes import BasicNewsRecipe + +class Kathimerini(BasicNewsRecipe): + title = 'Kathimerini' + __author__ = 'Pan' + description = 'News from Greece' + max_articles_per_feed = 100 + oldest_article = 100 + publisher = 'Kathimerini' + category = 'news, GR' + language = 'el' + no_stylesheets = True + remove_tags_before = dict(name='td',attrs={'class':'news'}) + remove_tags_after = dict(name='td',attrs={'class':'news'}) + remove_attributes = ['width', 'src','header','footer'] + + feeds = [(u'\u03a0\u03bf\u03bb\u03b9\u03c4\u03b9\u03ba\u03ae', + 'http://wk.kathimerini.gr/xml_files/politics.xml'), + (u'\u0395\u03bb\u03bb\u03ac\u03b4\u03b1', + ' http://wk.kathimerini.gr/xml_files/ell.xml'), + (u'\u039a\u03cc\u03c3\u03bc\u03bf\u03c2', + ' http://wk.kathimerini.gr/xml_files/world.xml'), + (u'\u039f\u03b9\u03ba\u03bf\u03bd\u03bf\u03bc\u03af\u03b1', + 'http://wk.kathimerini.gr/xml_files/economy_1.xml'), + (u'\u0395\u03c0\u03b9\u03c7\u03b5\u03b9\u03c1\u03ae\u03c3\u03b5\u03b9\u03c2', + 'http://wk.kathimerini.gr/xml_files/economy_2.xml'), + (u'\u0394\u03b9\u03b5\u03b8\u03bd\u03ae\u03c2 \u039f\u03b9\u03ba\u03bf\u03bd\u03bf\u03bc\u03af\u03b1', + 'http://wk.kathimerini.gr/xml_files/economy_3.xml'), + (u'\u03a0\u03bf\u03bb\u03b9\u03c4\u03b9\u03c3\u03bc\u03cc\u03c2', + 'http://wk.kathimerini.gr/xml_files/civ.xml'), + (u'\u039c\u03cc\u03bd\u03b9\u03bc\u03b5\u03c2 \u03a3\u03c4\u03ae\u03bb\u03b5\u03c2', + 'http://wk.kathimerini.gr/xml_files/st.xml')] + + def print_version(self, url): + return url.replace('http://news.kathimerini.gr/4dcgi/', 'http://news.kathimerini.gr/4dcgi/4dcgi/') + + diff --git a/resources/tanea.recipe b/resources/tanea.recipe new file mode 100644 index 0000000000..4e6cd09c3f --- /dev/null +++ b/resources/tanea.recipe @@ -0,0 +1,30 @@ +from calibre.web.feeds.recipes import BasicNewsRecipe + +class TaNea(BasicNewsRecipe): + title = u'Ta Nea' + __author__ = 'Pan' + oldest_article = 1 + max_articles_per_feed = 100 + no_stylesheets = True + + remove_tags_before = dict(name='div',attrs={'id':'print-body'}) + remove_tags_after = dict(name='div',attrs={'id':'text'}) + + feeds = [ + (u'\xce\x95\xce\xbb\xce\xbb\xce\xac\xce\xb4\xce\xb1', + u'http://www.tanea.gr/default.asp?pid=66&la=1'), + (u'\xce\x9a\xcf\x8c\xcf\x83\xce\xbc\xce\xbf\xcf\x82', + u'http://www.tanea.gr/default.asp?pid=67&la=1'), + (u'\xce\x9f\xce\xb9\xce\xba\xce\xbf\xce\xbd\xce\xbf\xce\xbc\xce\xaf\xce\xb1', + u'http://www.tanea.gr/default.asp?pid=68&la=1'), + (u'\xce\xa0\xce\xbf\xce\xbb\xce\xb9\xcf\x84\xce\xb9\xcf\x83\xce\xbc\xcf\x8c\xcf\x82', + u'http://www.tanea.gr/default.asp?pid=69&la=1'), + (u'\xce\x93\xce\xbd\xcf\x8e\xce\xbc\xce\xb5\xcf\x82', + u'http://www.tanea.gr/default.asp?pid=79&la=1'), + (u'\xce\xa1\xce\xb9\xcf\x80\xce\xad\xcf\x82', + u'http://www.tanea.gr/default.asp?pid=80&la=1'), + (u'\xce\x91\xce\xb9\xcf\x87\xce\xbc\xce\xad\xcf\x82', + u'http://www.tanea.gr/default.asp?pid=81&la=1')] + + def print_version(self, url): + return url.replace('http://www.tanea.gr/default.asp?pid=2', 'http://www.tanea.gr/default.asp?pid=96') From d5d8ec6a9c4a5f76743df75c5aeba85549c20b0c Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 17 Feb 2010 09:00:21 -0700 Subject: [PATCH 07/10] Wired UK by Darko Miletic --- resources/images/news/wired_uk.png | Bin 0 -> 647 bytes resources/recipes/wired_uk.recipe | 74 +++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 resources/images/news/wired_uk.png create mode 100644 resources/recipes/wired_uk.recipe diff --git a/resources/images/news/wired_uk.png b/resources/images/news/wired_uk.png new file mode 100644 index 0000000000000000000000000000000000000000..c807e36d1f47825ea779e09f82da8baece2f56ba GIT binary patch literal 647 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b zK-vS0-A-oPfdtD69Mgd`SU*F|v9*U87#KHrx;TbdoIX0));}arpl$xl--3cMk6G`i z9?@XkwR>S?q)={7PS4uT*0oy=&Hiv(|8MxmENpGrkNU)^@)(3=(mV?`fUC+(oBPE|jh=S~l!mT+9?nX<5TYi%^sAFss62gF1^_ZB8~ z2nT!2nlF^Ka6@5&g_m~ti4=)xX;Z?M_^?H;oi5RH+BR@oecx++i9au$^P=WNRCONh zmDsX)KjSfpC(|P=*5}AZee2uwb@qLovmTL|70GOUhA;Sajvw0?^L@p9(ML<}2)&oE zX|xWn=?iwR|G>|=bMwI!lV(r%X5Kze&_$;owj-z7xRx=M_@#%mbgZgq$HN4S|t~y0x1R~149E{10!8S^AH0I zD%(2h_me>FVdQ&MBb@ E0I~N1wg3PC literal 0 HcmV?d00001 diff --git a/resources/recipes/wired_uk.recipe b/resources/recipes/wired_uk.recipe new file mode 100644 index 0000000000..d0429f9573 --- /dev/null +++ b/resources/recipes/wired_uk.recipe @@ -0,0 +1,74 @@ + +__license__ = 'GPL v3' +__copyright__ = '2010, Darko Miletic ' +''' +www.wired.co.uk +''' + +from calibre import strftime +from calibre.web.feeds.news import BasicNewsRecipe + +class Wired_UK(BasicNewsRecipe): + title = 'Wired Magazine - UK edition' + __author__ = 'Darko Miletic' + description = 'Gaming news' + publisher = 'Conde Nast Digital' + category = 'news, games, IT, gadgets' + oldest_article = 32 + max_articles_per_feed = 100 + no_stylesheets = True + encoding = 'utf-8' + use_embedded_content = False + masthead_url = 'http://www.wired.co.uk/_/media/wired-logo_UK.gif' + language = 'en_GB' + extra_css = ' body{font-family: Palatino,"Palatino Linotype","Times New Roman",Times,serif} img{margin-bottom: 0.8em } .img-descr{font-family: Tahoma,Arial,Helvetica,sans-serif; font-size: 0.6875em; display: block} ' + index = 'http://www.wired.co.uk/wired-magazine.aspx' + + conversion_options = { + 'comment' : description + , 'tags' : category + , 'publisher' : publisher + , 'language' : language + } + + keep_only_tags = [dict(name='div', attrs={'class':'article-box'})] + remove_tags = [ + dict(name=['object','embed','iframe','link']) + ,dict(attrs={'class':['opts','comment','stories']}) + ] + remove_tags_after = dict(name='div',attrs={'class':'stories'}) + remove_attributes = ['height','width'] + + + def parse_index(self): + totalfeeds = [] + soup = self.index_to_soup(self.index) + maincontent = soup.find('div',attrs={'class':'main-content'}) + mfeed = [] + if maincontent: + st = maincontent.find(attrs={'class':'most-wired-box'}) + if st: + for itt in st.findAll('a',href=True): + url = 'http://www.wired.co.uk' + itt['href'] + title = self.tag_to_string(itt) + description = '' + date = strftime(self.timefmt) + mfeed.append({ + 'title' :title + ,'date' :date + ,'url' :url + ,'description':description + }) + totalfeeds.append(('Articles',mfeed)) + return totalfeeds + + def get_cover_url(self): + cover_url = None + soup = self.index_to_soup(self.index) + cover_item = soup.find('span',attrs={'class':'cover'}) + if cover_item: + cover_url = cover_item.img['src'] + return cover_url + + def print_version(self, url): + return url + '?page=all' From 9a7f6259569ce0ff160c8eb3240b4b3bd7bdaf32 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 17 Feb 2010 10:47:04 -0700 Subject: [PATCH 08/10] ... --- resources/recipes/wired_uk.recipe | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/recipes/wired_uk.recipe b/resources/recipes/wired_uk.recipe index d0429f9573..4c682feef2 100644 --- a/resources/recipes/wired_uk.recipe +++ b/resources/recipes/wired_uk.recipe @@ -59,13 +59,13 @@ class Wired_UK(BasicNewsRecipe): ,'url' :url ,'description':description }) - totalfeeds.append(('Articles',mfeed)) + totalfeeds.append(('Articles', mfeed)) return totalfeeds def get_cover_url(self): cover_url = None soup = self.index_to_soup(self.index) - cover_item = soup.find('span',attrs={'class':'cover'}) + cover_item = soup.find('span', attrs={'class':'cover'}) if cover_item: cover_url = cover_item.img['src'] return cover_url From e84310af6397f2afb25aa0011289482be0c60793 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 17 Feb 2010 11:30:59 -0700 Subject: [PATCH 09/10] MOBI Output: Encode titles as UTF-8 in the PalmDoc header as well as the EXTH header, since there are apparently MOBI readers that use the title from the PalmDoc header in preference to the title from the EXTH header. --- src/calibre/ebooks/mobi/writer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/ebooks/mobi/writer.py b/src/calibre/ebooks/mobi/writer.py index 8de702a617..0f26e25609 100644 --- a/src/calibre/ebooks/mobi/writer.py +++ b/src/calibre/ebooks/mobi/writer.py @@ -1376,7 +1376,7 @@ class MobiWriter(object): self._text_length, self._text_nrecords-1, RECORD_SIZE, 0, 0)) # 0 - 15 (0x0 - 0xf) uid = random.randint(0, 0xffffffff) - title = str(metadata.title[0]) + title = unicode(metadata.title[0]).encode('utf-8') # The MOBI Header # 0x0 - 0x3 From d45da570474791f33aa09fdbc3aab5bc3911d596 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 17 Feb 2010 11:46:21 -0700 Subject: [PATCH 10/10] MOBI metadata: Handle setting of non-ascii titles correctly --- src/calibre/ebooks/metadata/mobi.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/calibre/ebooks/metadata/mobi.py b/src/calibre/ebooks/metadata/mobi.py index 1de73d7dd4..3791a14b22 100644 --- a/src/calibre/ebooks/metadata/mobi.py +++ b/src/calibre/ebooks/metadata/mobi.py @@ -187,6 +187,8 @@ class MetadataUpdater(object): def create_exth(self, new_title=None, exth=None): # Add an EXTH block to record 0, rewrite the stream # self.hexdump(self.record0) + if isinstance(new_title, unicode): + new_title = new_title.encode(self.codec, 'replace') # Fetch the existing title title_offset, = unpack('>L', self.record0[0x54:0x58]) @@ -219,12 +221,7 @@ class MetadataUpdater(object): new_record0 = StringIO() new_record0.write(self.record0[:0x10 + mobi_header_length]) new_record0.write(exth) - if new_title: - #new_record0.write(new_title.encode(self.codec, 'replace')) - new_title = (new_title or _('Unknown')).encode(self.codec, 'replace') - new_record0.write(new_title) - else: - new_record0.write(title_in_file) + new_record0.write(new_title if new_title else title_in_file) # Pad to a 4-byte boundary trail = len(new_record0.getvalue()) % 4