
    Z'i`                        d dl Zd dlZd dlZd dlZd dlZd dlZ	 d dlmZ d dl
mZmZmZmZ d dlmZ dZi dddd	d
dddddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3Zd4ej&                  fd5ej(                  fd6ej*                  fd7Zd8d9d:d;Zd<d=d>d?d@dAdBdCdDdEdFdGdHdIdJZdKdLdMZi dNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmdndoi dpdqdrdsdtdudvdwdxdydzd{d|d}d~dddddddddddddddddddi dddddddddddddddddddddddddddddddddddddddddddd	Z G d de      Zy#  d dl	mZ Y _xY w)    N)OrderedDict)hexdumpdecodeVarinttoStrtoByte)compressionFzAdobe Readerz.pdfADBEPalmDOCTEXtREAdBDictyBVokBDICzDB (Database program)DB99DBOSz	eReader 1PNRdPPrsz	eReader 2DataPPrszFireViewer (ImageViewer)vIMGViewHanDBasePmDBPmDBInfoViewInfoINDBiSiloToGoToGoziSilo 3SDocSilXJFileJbDbJBasz	JFile ProJfDbJFilLISTDATALSdbMobileDBMdb1Mdb1
MobiPocketBOOKMOBIPluckerDataPlkrDataSprdSM01SMemTEXtTlDcInfoTlIfDataTlMlDataTlPtdataTDBPTdatTideToRaTRPWzTXTGPlmBDOCWrdS)
QuickSheet	SuperMemoTealDocTealInfoTealMeal	TealPaintThinkDBTides
TomeRaiderWeasel	WordSmithzno compressionzPalmDOC compressionzHUFF/CDIC compression)      iHD  zno encryptionzOld Mobipocket EncryptionzMobipocket Encryption)r   r9   r:   zMobipocket BookzPalmDoc BookAudioz%mobipocket? generated by kindlegen1.2zKF8: generated by kindlegen2News	News_FeedNews_MagazinePICSWORDXLSPPTTEXTHTML)r:               i  i  i  i  i  i  i    i  zCP1252 (WinLatin1)zUTF-8)i    r9   drm_server_idr:   drm_commerce_idrE   drm_ebookbase_book_idd   zauthor      <dc:Creator>e   zpublisher       <dc:Publisher>f   zimprint         <Imprint>g   z$description         <dc:Description>h   z)isbn        <dc:Identifier scheme="ISBN">i   z8subject     Could appear multiple times     <dc:Subject>j   zpublishingdate      <dc:Date>k   zreview      <Review>l   z$contributor         <dc:Contributor>m   zrights      <dc:Rights>n   z8subjectcode         <dc:Subject BASICCode="subjectcode">o   ztype        <dc:Type>p   zsource      <dc:Source>q   zUasin    Kindle Paperwhite labels books with "Personal" if they dont have this record.r   versionnumbers   zDsample  0x0001 if the book content is only a sample of the full bookt   zSstartreading    Position (4-byte offset) in file at which to open when first openedu   zcadult   Mobipocket Creator adds this if Adult only is checked on its GUI; contents: "yes"   <Adult>v   z-retail price    As text, e.g. "4.99"    <SRP>w   zIretail price currency   As text, e.g. "USD"     <SRP Currency="currency">y   zKF8 BOUNDARY Offset}   zcount of resources   zKF8 cover URI   Unknown   z=Dictionary short name   As text     <DictionaryVeryShortName>   zwcoveroffset     Add to first image field in Mobi Header to find PDB record containing the cover image   <EmbeddedCover>   zothumboffset     Add to first image field in Mobi Header to find PDB record containing the thumbnail cover image   hasfakecover   zCreator Software    Known Values: 1=mobigen, 2=Mobipocket Creator, 200=kindlegen (Windows), 201=kindlegen (Linux), 202=kindlegen (Mac).   zCreator Major Version   zCreator Minor Version   zCreator Build Number   	watermark   z[tamper proof keys   Used by the Kindle (and Android app) for generating book-specific PIDs.i,  fontsignaturei  zQclippinglimit   Integer percentage of the text allowed to be clipped. Usually 10.i  publisherlimiti  i  zCttsflag     1 - Text to Speech disabled; 0 - Text to Speech enabledi  i  i  i  i  i  i  i  z?cdetype  PDOC - Personal Doc; EBOK - ebook; EBSP - ebook samplei  lastupdatetimeupdatedtitlez.asin    I found a copy of ASIN in this record.zother titlezother authorzother publisherzlanguage        <dc:language>z1alignment   I found horizontal-lr in this record.zkindlegen version)	i  i  i  rI   i
  i  i  i  i  c                       e Zd ZdZg dZg dZg dZ e       Z e       Z	 e       Z
 e       Z e       Z e       ZdZd Zd Zd Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd ZddZy)BookMobia&  
    Mobi format:
    `Palm Database Format`_

    `MOBI Format`_

    .. _`Palm Database Format`: http://wiki.mobileread.com/wiki/PDB#Palm_Database_Format
    .. _`MOBI Format`: http://wiki.mobileread.com/wiki/MOBI

    mobi record order
    -----------------
    1. first content. normal is 1.
    2. text record
    #. first non-book record
    #. ortographic
    #. indx record
    #. huff/cdic record
    #. first image record
    #. huff/cdic table record
    #. last content record
    #. flis record
    #. fcis record
    #. srcs record
    ))name32sr   )
attributes>H    )versionr}   "   )creationDate>L$   )modificationDater   (   )lastbackupDater   ,   )modificationNumberr   0   )	appInfoIDr   4   )
sortInfoIDr   8   )type4s<   )creatorr   @   )uniqueIDseedr   D   )nextRecordListIDr   H   )numberOfRecordsr}   L   ))r   r}   r   )unusedr}   r:   )
textLengthr   rF   )recordCountr}      )
recordSizer   
   )currentPositionr      )encryptionTyper}   r   )6)
identifierr      )headerLengthr      )mobiTyper      )textEncodingr      )uniqueIDr   r~   )fileVersionr   r   )ortographicIndexr   r   )inflectionIndexr   r   )
indexNamesr   r   )	indexKeysr   r   )extraIndex0r   r   )extraIndex1r   r   )extraIndex2r   r   )extraIndex3r   r   )extraIndex4r   r   )extraIndex5r   r   )firstNonBookIndexr   P   )fullNameOffsetr   T   )fullNameLengthr   X   )localer   \   )inputLanguager   `   )outputLanguager   rN   )
minVersionr   rR   )firstImageIndexr   rV   )huffmanRecordOffsetr   rZ   )huffmanRecordCountr   r_   )huffmanTableOffsetr   x   )huffmanTableLengthr   |   )	exthFlagsr      )
unknown13212s   )
unknown14416s   )
unknown160r      )
unknown164r      )	drmOffsetr      )drmCountr      )drmSizer      )drmFlagsr      )
unknown184z>Q   )firstContentRecordNumberr}      )lastContentRecordNumberr}      )
unknown196r      )fcisRecordNumberr   rh   )fcisRecordCountr   rm   )flisRecordNumberr   rq   )flisRecordCountr      )
unknown2168s   )srcsRecordNumberr      )srcsRecordCountr      )numberOfCompilationDataSectionsr   rG   )
unknown236r      )extraRecordDataFlagsr      )indxRecordOffsetr      )
unknown248r   rH   )
unknown252r      Nc                 :   t        |t              rt        |d      }n|}|| _        | j                  j	                  dd       |j                  d      }| j                  D ].  \  }}}t        j                  |||      \  }|| j                  |<   0 |j	                  d       |j                  | j                  d   dz        }t        d| j                  d         D ];  }	t        j                  d||	dz        \  }}|dz  }
|dz  }||
|f| j                  |	<   = t        | j                  d	         t        | j                  d
         }t        | j                  d         | j                  d<   || j                  d<   | j                  | j                  d         | j                  d<   | j                  | j                  d         | j                  d<   | j                  d      }| j!                         s| j#                         r| j$                  D ].  \  }}}t        j                  |||      \  }|| j&                  |<   0 | j&                  d   dk(  r&t        j                  d|d      \  | j&                  d<   | j)                  t*        | j&                  d         | j                  d<   | j)                  t,        | j&                  d         | j                  d<   |t.        d   k(  r3t1        |      }| j2                  D ]5  \  }}}||k  r n*t        j                  |||      \  }|| j4                  |<   7 | j&                  d   dk(  rN| j4                  d   dk7  r<|| j4                  d   | j4                  d   | j4                  d   z    | j4                  d<   | j&                  d   dk(  r6t        j                  d|d| j4                  d   z         \  | j4                  d<   | j4                  d   dkD  r| j4                  d    d!k\  r| j4                  d"   d#z  rd| j4                  d   z   }d}t        j                  d$||      \  }}}t        |      d%k7  rt7        ||||z           t9        d&|z        |d'z  }d}	|	|k  r|t        j                  d|||z         \  }}t        j                  d(|dz
  z  |||z   dz         \  }|| j:                  |<   t<        r|t>        vrtA        ||d)       ||z  }|	dz  }	|	|k  r|t        j                  d(| j4                  d*   z  || j4                  d+         \  }|rt        |      | j                  d<   | j4                  d    | j                  d,<   t        d-| j:                  v r| j:                  d-   nd.      | j                  d/<   | j)                  tB        | j4                  d0         | j                  d0<   | j)                  tD        | j4                  d1         | j                  d2<   | j4                  d3   dk7  | j                  d4<   y y )5Nrbr   N   r   r   >LLl      ~ i r   r   rz   titleidentr   r   r   r9   r      type1KeyDatar   
encryptionr   r:   r       r   drmDatar   r   r   r      r   r   z>4sLLEXTHzexth header error: %sr   z%dszunknown typer   r   r   rN   unknownauthorr   r   encodingr   srcs)#
isinstancestropenfseekreadpalmdb_formatstructunpack_fromheaderrangerecordsr   bookdatetimeFromValue
loadRecord	isPalmdocisMobipocketpalmdoc_formatpalmdoctypeDesccompression_typeencryption_typepd_file_codelenmobi_formatmobir   	Exception	mobi_exthDEBUGmobi_exth_typeprint	mobi_typeencoding_type)selffiler  r  keyu_fmtoffsetvaluer  countr|   r   r   record0record0_length	exth_addr	exthIdent
exthLength	exthCount
recordTyperecordLengthdatar   s                          $/opt/sopds/book_tools/pymobi/mobi.py__init__zBookMobi.__init__  s   dC T4 AAAa"&"4"4 	%C''vv>FE$DKK	% 	
r
&&%67!;<1dkk*;<= 	AE"..uguqyIMFE+Jx'H#):x"@DLL		A
  F 34eDKK	<R6ST"4;;v#67		'"		'$($:$:4;;~;V$W		.!(,(>(>t{{K]?^(_		$%//!$>>t002&*&9&9 *"UF++E7FC$)S!* ||,-2060B0B1-^,
 (,}} ]+(DIIm$ '+mm-.'DIIl# L.. \N&*&6&6 '"UF!F*++E7FC!&		#	' -.!3IIk*j8'.IIk*IIk*TYYy-AA(		)$ ||,-2-3-?-?499^44.*		.) 		.)D0IIl+q0IIk*T1 !499^#<<	393E3E40	:y
 #v-GIi*.DEF#$;i$GHH"i'/5/A/A!F*0,,J #..!12!F*Q.0ED 26DNN:.)^;!*dNCl*FQJE i' ''		"233		*+FE
 %*5\		'"#'99\#:DIIi "'sdnn?Ts(;Zc"dDIIh$(MM		*%%DIIj! %)MM		.)%DIIj! "&+=!>*!LDIIfU /    c                 8    | j                   j                  |      S N)r  get)r-  rz   s     r=  __getitem__zBookMobi.__getitem__}  s    yy}}T""r?  c                 ,    t        | j                        S rA  )r#  r  r-  s    r=  __len__zBookMobi.__len__  s    499~r?  c                 6    | j                   j                         S rA  )r  
itervaluesrE  s    r=  __iter__zBookMobi.__iter__  s    yy##%%r?  c                 4    | j                   d   t        d   k(  S )Nr   r   r  r"  rE  s    r=  r  zBookMobi.isMobipocket  s    yy!\,%???r?  c                 4    | j                   d   t        d   k(  S )Nr   r	   rK  rE  s    r=  r  zBookMobi.isPalmdoc  s    yy!\)%<<<r?  c                 F   t         | j                  d      d   } |       | _        t        | j                  t        j                        r| j                  | j                  d         }| j                  j                  |       t        d| j                  d         D ]>  }| j                  | j                  d   |z         }| j                  j                  |       @ t        j                  d   dk  r| j                  j                  }|S | j                  j                  }|S )Nr   r9   r   r   r   rE   )r   r  r   r  Huffcdicr  r%  loadHuffr  loadCdicsysversion_infounpackunpack3)r-  compression_classrec_huffcrec_cdicrS  s         r=  unpackFunctionzBookMobi.unpackFunction  s    ,T\\--HI!L,.d&&(<(<=tyy1F'GHH%%h/1dii(<=> 4??4995J+Ka+OP  ))(34 A"%%,,F  %%--Fr?  c                 D    ||v r||   }t        |t              r|d   S |S y)Nr   r  )r  tuple)r-  typesr2  descs       r=  r  zBookMobi.typeDesc  s-    E><D$&Awr?  c                 (   | j                   |   d   }| j                  j                  |       || j                  d   dz
  k(  r| j                  j	                         }|S | j                   |dz      d   }| j                  j	                  ||z
        }|S )z-
        load palm database's record
        r   r   r9   )r  r  r  r  r  )r-  record_indexr1  recordoffset2s        r=  r  zBookMobi.loadRecord  s     l+A.FDKK(9:Q>?VV[[]F  ll<!#34Q7GVV[[6!12Fr?  c                     |dz  }|rt        j                   ddd      }nt        j                   ddd      }|t        j                  |      z  }|S )z
        If the time has the top bit set, it's an unsigned 32-bit number counting from 1st Jan 1904
        If the time has the top bit clear, it's a signed 32-bit number counting from 1st Jan 1970.
        l        ip  r9   i  )seconds)datetime	timedelta)r-  r2  flagtimes       r=  r  zBookMobi.datetimeFromValue  sS    
 z!$$T1a0D$$T1a0D""511r?  c                     |S rA   )r-  r`  s     r=  decryptzBookMobi.decrypt  s    r?  c                     t        j                  d|d      \  }|dk(  ry|dk(  ryt        j                  d|d      }|d   d	k(  ry
t        j                  d|d      \  }d|z  S )Nr   r   i8FIGz.gifl   GN z.pngz>HHHLrE   iFIFJz.jpgz>4sz.%s)r  r  )r-  r`  r   s      r=  imageExtzBookMobi.imageExt  sq    ##D&!4Jj ""7FA68z!##E615u}r?  c                     | j                  |      }| j                  |      }||}t        |d      5 }|j                  |       d d d        t        j
                  j                  |      S # 1 sw Y   (xY w)Nwb)r  rl  r  writeospathbasename)r-  numrr  recextimg_filer  s          r=  saveRecordImagezBookMobi.saveRecordImage  si    ooc"mmC %s+(D! 	QGGCL	ww))	 	s   A..A7c                      fd}t        d       t         j                  d         d}|D ]8  }t        j                  |t        j
                        }|j                  ||      }:  j                  d   dk(  rd}nd j                  d   z  }t        j                  d	t        d
|z        |t        j
                        }t        d       |S )Nc                    t        | j                  d            }|z   dz
  }d|fz  }t        j                  j	                  d       t        j                  j                          j                  ||      }t        d|z        S )Nr9   z%s_img_%05d.z<img src="%s")intgrouprQ  stdoutro  flushrw  r   )moimg_idxrs  img_basenamerv  rr  img_idx_baser-  s        r=  replz'BookMobi.loadTextResource.<locals>.repl  sw    "((1+&G(1,C(Hg+>>LJJS!JJ++C>H/H455r?  z
Dump imager   )s   <img\s+recindex=['"](\d+)['"]s5   <img\s+src=['"]kindle:embed:(\d+)\?mime=image/jpg['"]r   rJ   zutf-8zcp%ds   <head>zI<head>
<meta http-equiv="Content-Type" content="text/html; charset=%s" /> )r*  r{  r%  recompileIsubr   )	r-  r<  rr  r  img_patternpatternregexcharsetr  s	   ` `     @r=  loadTextResourcezBookMobi.loadTextResource  s    	6 	l499%678
 # 	)GJJw-E99T4(D	) 99^$-Gtyy88Gvv_biijDD	
 	b	r?  c                     | j                   d   }| j                   d   }| j                         }g }t        d| j                  d   z         t        d| j                  d   z         t        d| j                  d   z         t        d	       t	        d
|d
z         D ]  }| j                  |      }| j                  d   d
z	  }|d
z  r8t        j                  d|dd  d      \  }	t        |	      }
|d |
  }|d
z  }|d
z  r8| j                  d   d
z  r*t        j                  d|dd  d      \  }|dz  d
z   }|d |  }| j                  |      }t        j                  j                  d       t        j                  j                          |j                   ||              dj!                  |      }||d  }|d | }t        j                  j                  d|z         t"        j$                  j'                  |      d   }|rt        j                  j                  dt)        |      z         d|z  }t+        |d      5 }|j                  |       d d d        t-        j.                  ddt"        j$                  j1                  |      z  |t,        j2                        }t        d       | j                  d   dk7  r| j5                  ||      }t+        |d      5 }|j                  |       d d d        d| j6                  v rWt        d       t        j8                  d| j6                  d         \  }|| j                  d   z  }| j;                  |d|z         t        d        y # 1 sw Y   xY w# 1 sw Y   xY w)!Nr   r   	Title: %sr   zCompression Type: %sr   zEncryption Type: %sr  zDump html/cssr9   r   r   r   z>BrE   rz  r?  zhtml: %dz
 / css: %dz%s.cssrn  z<head>z9<head>
<link rel="stylesheet" href="%s" type="text/css"/>r  r   r  ri   z
Dump coverz%s_coverzUnpack MOBI successfully)r  rY  r*  r  r  r  r%  r  r  r   rj  rQ  r}  ro  r~  appendjoinrp  rq  splitextr#  r  r  r  rr  r  r  r'  rS  rw  )r-  output_filerec_numtext_lengthrS  r<  rnr`  
extraflagsvintfintmb_num	data_textdata_cssrr  css_filenamer  cover_rns                     r=  
unpackMobizBookMobi.unpackMobi  s2   ,,}-ll<0$$&kDIIg../$tyy'??@#dii&==>o7Q;' 	(B__R(F#9:a?Js"**4a@#D)$q 
 s" yy/036 !,,T6"#;B 3,!+&)\\&)FJJS!JJKKv''	(( HHTN	[\*l{+	

k1277##K03JJ\CM9:#h.LlD) "Q!"LrwwO_O_`lOmm	I 	b	99&':5--iBI+t$ 	GGI	 $.. ,dDNN3,?@IH		"344H  :+@A()'" "	 	s   M'M4'M14M=c                     d| j                   v rJt        j                  d| j                   d         \  }|| j                  d   z  }| j	                  |      }|S y )Nri   r   r   )r'  r  rS  r%  r  )r-  r  rt  s      r=  unpackMobiCoverzBookMobi.unpackMobiCover0  sS    $.. dDNN3,?@IH		"344H//(+CJr?  c           	      
   | j                   d   }| j                   d   }t        d| j                  d   z         |dk(  s|dk(  rt        d       y t        d|z         |rt        d	|z         t        |d
      }t	        |||z         D ]  }t
        j                  j                  d       t
        j                  j                          | j                  |      }t        j                  d|d      }|d   dk(  sq|j                  |dd          |j                          t        d       t        d|z         t        |d
      5 }| j                  j                  d       |j                  | j                  j                  d             t!        j                   d| j                  j                  d| j"                  d   z              }	t        d       | j$                  |   d   }
t	        d|      D ]e  }t
        j                  j                  d       t
        j                  j                          |
|dz  z   }t        j&                  d|	||z   dz  |       g | j$                  ||z      d   |
z
  |dz  z
  }t	        ||z   | j"                  d         D ]o  }t
        j                  j                  d       t
        j                  j                          | j$                  |   d   |z
  }t        j&                  d|	|dz  |       q |j                  |	       t        d       | j$                  d   d   |j)                         z
  }|r*|j                  | j                  j                  |             t        d       t!        j                   d| j                  d            }t        j&                  d|ddd       |j                  |       t	        d|      D ]a  }t
        j                  j                  d       t
        j                  j                          | j                  |      }|j                  |       c d}t	        |||z         D ]P  }t
        j                  j                  d       t
        j                  j                          |j                  |       R t	        ||z   | j"                  d         D ]a  }t
        j                  j                  d       t
        j                  j                          | j                  |      }|j                  |       c t        d       d d d        t        d       y # 1 sw Y   xY w)Nr   r   r  r   r  r   zNo SRCS section.zFind SRCS: %dzOutput ZIP file: %s rn  rz  z>4LiSCRSr   r  zOutput MOBI file: %sr   Br   r   zFix record offsetr:   r   zWrite recordr   r   r9   s     zRemove SRCS successfully)r%  r*  r  r  r  rQ  r}  ro  r~  r  r  r  closer  r  r  arrayr  r  	pack_intotell)r-  outmobioutsrcssrcs_rnsrcs_rcr  r  rt  r  recordlist_datasrcs_offsetr3  
fix_offsetr1  gapToDataLengthr4  	srcs_datas                    r=  
removeSrcszBookMobi.removeSrcs8  sY   ))./))-.kDIIg../j GqL$%o'((723Wd#AGWw%67 &

  %

  "oob)++E3:!9
*GGCH%& GGIb	$w./'4  .	AFFKKNGGDFFKKO$#kk#tvv{{1t{{K\?];]/^_O%&,,w/2Kq'* [

  %

  "(5194
  5A8MzZ	[
 \\'G"34Q7+ERSSFGg-t{{;L/MN L

  %

  "!\\"-a069
  Q
K	L
 GGO$"I"ll1oa01668;OO45.!kk#tq'9:GUGS*a@GGGAw' 

  %

  "oob)	
 $IGWw%67 #

  %

  "	"#
 Gg-t{{;L/MN 

  %

  "oob)	
 "I].	^ 	()_.	 .	s   O&T??UrA  ) __name__
__module____qualname____doc__r  r  r$  r   r  r  r  r%  r'  r  r   r>  rC  rF  rI  r  r  rY  r  r  r  rj  rl  rw  r  r  r  r  ri  r?  r=  ry   ry      s    0M"N7Kp ]FmGmG=DI=DKyNv#&@=
*@8*tE*r?  ry   )os.pathrp  rd  r  r  r  rQ  collectionsr   ordereddictbook_tools.pymobi.utilr   r   r   r   book_tools.pymobir   r(  r"  UncompressionPalmdocrN  r   r!  r+  r,  r)  objectry   ri  r?  r=  <module>r     s      	  
(' H G )

 
 
	
 
 
 
 
 
 
 
 
 
 
 
  
!" 
#$ !+ * * * * * * * * * *9> 	+334{223#[%9%9:  " 
			0	'										" ==	= 	 = 	#	=
 	)= 	$= 	/= 	4= 	C= 	(= 	= 	/= 	"= 	C= 	 =  	"!=" 	`#=$ %=& 	O'=( 	^)=* 	n+=, 	8-=. 	T/=0 	1=2 	3=4 5=6 7=8 	H9=:   
C;=< 	z==> ?=@   
SA=B 	 C=D 	 E=F 	G=H I=J 	fK=L M=N 	\O=P 	Q=R S=T 	NU=V W=X Y=Z [=\ ]=^ _=` a=b c=d 	Je=f 	g=h 
	9				(	<		y=@n*v n*K(''s   E4 4E?