From 8eb97bbe83232e0591f93b21b311f22be3fbbdd2 Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Fri, 14 Sep 2012 18:01:18 +0200 Subject: [PATCH 1/7] Never build an AZW3 periodical, even if it's the preferred output format (FIXME: this should ideally handle mobi both & mobi new formats, too) --- src/calibre/gui2/tools.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/calibre/gui2/tools.py b/src/calibre/gui2/tools.py index 36c1a6f30f..b3375ad842 100644 --- a/src/calibre/gui2/tools.py +++ b/src/calibre/gui2/tools.py @@ -234,6 +234,9 @@ class QueueBulk(QProgressDialog): def fetch_scheduled_recipe(arg): # {{{ fmt = prefs['output_format'].lower() + # Never use AZW3 for periodicals... + if fmt == 'azw3': + fmt = 'mobi' pt = PersistentTemporaryFile(suffix='_recipe_out.%s'%fmt.lower()) pt.close() recs = [] From 7690d8a97dbaf2ef3860dcb23a5d1696442412f3 Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Fri, 14 Sep 2012 18:02:50 +0200 Subject: [PATCH 2/7] Set the KF8 thumbnail URI (EXTH 129) in a similar manner as KindleGen 2.5 --- src/calibre/ebooks/mobi/writer8/exth.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/calibre/ebooks/mobi/writer8/exth.py b/src/calibre/ebooks/mobi/writer8/exth.py index 508b77ce5b..9362a07d81 100644 --- a/src/calibre/ebooks/mobi/writer8/exth.py +++ b/src/calibre/ebooks/mobi/writer8/exth.py @@ -11,7 +11,7 @@ import re from struct import pack from io import BytesIO -from calibre.ebooks.mobi.utils import utf8_text +from calibre.ebooks.mobi.utils import (utf8_text, to_base) from calibre.utils.localization import lang_as_iso639_1 EXTH_CODES = { @@ -30,6 +30,7 @@ EXTH_CODES = { 'startreading': 116, 'kf8_header_index': 121, 'num_of_resources': 125, + 'kf8_thumbnail_uri': 129, 'kf8_unknown_count': 131, 'coveroffset': 201, 'thumboffset': 202, @@ -159,7 +160,10 @@ def build_exth(metadata, prefer_author_sort=False, is_periodical=False, if thumbnail_offset is not None: exth.write(pack(b'>III', EXTH_CODES['thumboffset'], 12, thumbnail_offset)) - nrecs += 1 + thumbnail_uri_str = bytes('kindle:embed:%s' %(to_base(thumbnail_offset, base=32, min_num_digits=4))) + exth.write(pack(b'>II', EXTH_CODES['kf8_thumbnail_uri'], len(thumbnail_uri_str) + 8)) + exth.write(thumbnail_uri_str) + nrecs += 2 if start_offset is not None: try: From 6e93e8fada9735a838f0b16c81536a91563f54f2 Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Fri, 14 Sep 2012 18:04:44 +0200 Subject: [PATCH 3/7] Add an icon for AZW3, AZW2 & TOPAZ file formats. Use the same mimetypes as Amazon (on the Kindle Touch) for a bunch of Amazon formats Tweak the xdg mimetypes xml file to actually be taken into account (apparently really needs to be a .xml) --- imgsrc/mimetypes/azw2.svg | 237 +++++ imgsrc/mimetypes/azw3.svg | 237 +++++ imgsrc/mimetypes/mobi.svg | 42 +- imgsrc/mimetypes/tpz.svg | 237 +++++ resources/images/mimetypes/azw2.png | Bin 0 -> 8343 bytes resources/images/mimetypes/azw3.png | Bin 0 -> 7815 bytes resources/images/mimetypes/mobi.png | Bin 7489 -> 7992 bytes resources/images/mimetypes/tpz.png | Bin 0 -> 8372 bytes resources/mime.types | 1207 ++++++++++++----------- src/calibre/gui2/__init__.py | 7 +- src/calibre/gui2/convert/azw3_output.py | 2 +- src/calibre/linux.py | 45 +- 12 files changed, 1399 insertions(+), 615 deletions(-) create mode 100644 imgsrc/mimetypes/azw2.svg create mode 100644 imgsrc/mimetypes/azw3.svg create mode 100644 imgsrc/mimetypes/tpz.svg create mode 100644 resources/images/mimetypes/azw2.png create mode 100644 resources/images/mimetypes/azw3.png create mode 100644 resources/images/mimetypes/tpz.png diff --git a/imgsrc/mimetypes/azw2.svg b/imgsrc/mimetypes/azw2.svg new file mode 100644 index 0000000000..1c3c718b0b --- /dev/null +++ b/imgsrc/mimetypes/azw2.svg @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + Kindlet + + + + + diff --git a/imgsrc/mimetypes/azw3.svg b/imgsrc/mimetypes/azw3.svg new file mode 100644 index 0000000000..c60a7070f9 --- /dev/null +++ b/imgsrc/mimetypes/azw3.svg @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + KF8 + + + + + diff --git a/imgsrc/mimetypes/mobi.svg b/imgsrc/mimetypes/mobi.svg index 970456b0cb..9089dac15c 100644 --- a/imgsrc/mimetypes/mobi.svg +++ b/imgsrc/mimetypes/mobi.svg @@ -8,10 +8,37 @@ xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.0" width="128" height="128" - id="svg2606"> + id="svg2606" + inkscape:version="0.48.3.1 r9886" + sodipodi:docname="mobi.svg" + inkscape:export-filename="/home/niluje/Patchland/calibre/imgsrc/mimetypes/mobi.png" + inkscape:export-xdpi="90" + inkscape:export-ydpi="90"> + mobi + style="font-size:28px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans">mobi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + Topaz + + + + + diff --git a/resources/images/mimetypes/azw2.png b/resources/images/mimetypes/azw2.png new file mode 100644 index 0000000000000000000000000000000000000000..229d98ed3878a0516fc48d851b6850ea974d1c4d GIT binary patch literal 8343 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 W@R6?h=(p%Hfbv@n`AS)fPyYdB%Xkq0 literal 0 HcmV?d00001 diff --git a/resources/images/mimetypes/azw3.png b/resources/images/mimetypes/azw3.png new file mode 100644 index 0000000000000000000000000000000000000000..04e913b288f7f6fa7d528dd13de4ce40b86b133b GIT binary patch literal 7815 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 MHC@$eWy{e20}>En0{{R3 literal 0 HcmV?d00001 diff --git a/resources/images/mimetypes/mobi.png b/resources/images/mimetypes/mobi.png index cb1230a15baf7b69fad77fe01a0fba92564107df..0446021706726da22d33881dbc8d31c83f75df48 100644 GIT binary patch literal 7992 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 V*f9Ub1ghL18A(Nn3Nhor{{fb3j)MRI literal 7489 zcmX9@Wmr^A8(w+=fhDCo7U>X>?pnGLVF5{zZde+nq(M}=6$$BHQbJg|LqG}XTzcW# z_xi4L=FE@tV`iSZ@8_O4JsmY70$Kt906?Unu55sw!~YvVT=ch3)@B4f;o3sflmUP!zrG~PCQ9#aNZr~@1t=vI5<5d}vCn9}9-Gbd-&$9Rfj+ErhP5Ywif5PO3vIOb{`kepRrxASf@`CRc%;5U}$lLtnOvB?~;R zEyT4wy6K(mlAUF!iHByMY6qUNlk};!z>};Av59p4pUr0XrkoHKk2e_DM!gB)WCarN zV-9ZY|NagoV~{dGiT-o<#Y5sfImU!b7``6Wnq(nCB=s79p)2!Xvmglj{uI`UQQ8_G{P=Ggpn=2As2A(h z2ir+yi_69IUKO+^<9SZaasG-y{L#yELk89d%)?6)a$PSzzvT_*^Wu^ssS+r8KBPxdU@>1EhZ-1A zRdcPJXoO_h$!TkwH;?001H(nm3@zn3`P_N_M&Gxi)$HRBG<|1VBSdPleivYp(LBVDjlNw=GlG(3Z^7p~<2&`8!L5HUm!0dVCAD)UGqbYzpKtC~MevUB25gds zBELgR+uZ;T<9Uebap_`$>Ti`rMXa@9|4wWkYRldWblp$Y?2pmRY&}{snhv$|N(hQ65AnqoUsbygjQhrC9%1T%+ zbJepBaI=m8At<9ncb9JVfbYEJU{bEsi@-B>_b!xQ(b(SX_eFR}yXSl5@(5iyq*3I( zY{>18w~NAi$xP)B*Pg#&=h_wDzhjuS`EVzMUe+7=+eof0);nxm-I>?g;&AEYtoO%} zSDMvE!b9#bf7tZlGKO5}<2CE6cTocP&BLdYqGY7bf{jc#&s0B9_iU5Mi8_r6SOr9I zm_kbC;;v5by~jEBw9xh{g=CejbkvYAZr<+KsC~58gg_P_P6wYb zN-uaA5;IBjSk=?}TpPD<_PX_n|pOmEJp-HW&w@tA0a{spU3fIWO?f8iUB)JD=-YL80R-t=`Y- zFYXiiPerv+cq9(nA7}vJ_})74wT8pNR}Rgs5s_^G6nraSZJ;udL7e|LPh1f0A*Nf) zsp>RMcR>Uexiep=;EJGv_5NH{oMba7IpzXZvuxXhL+2popE3Giys+%Xu&8MHv zrK>ZujP@B4$0AoL0wG6X#|rlTvBO@Y>+7p&e$@J`VKTg57*B*l?vrKkX5Kj0Axx!+4&Af*UtjuZg zmnFpwjGL>VrWmXlPYCdBDJ!fWd;Bu42%VdnvUTx;Kp=cIO7h5A+WXM3x$Sn3+v77$ z#^xbi=knS53YU$)RZIJP3ZIh}tXDLtmwqPCE-if-dNwYoN`f8bjB0>0p=zg#x*eb- z^Vr=pe0ap}*VN}rWh>gl=k)V4+jS!Xjt}=Y;j|g6LHkve7R|(AE<6u&Ccke` z$KSqv)3`puA*2$t8v^|m(%$jzYw^^|kx2F3pPQVTQiMPVk2}tZ$+>j2uyaKm#_als zQn{&m1A-zCx0?t(rXT~KyX)6Nv%N^U@jRKCSKE9cCF9~^FPo+X@~85Ov)`5UzHzhU z0vG5UNncDTb=>ZK|7Kd*m-E8=da+0)?tC^sG1M&RU_ppe>r=`HZmmz!fx_QSs_I}= z6W7+n{se|zPWf4W@%ljK%tTs{17PSy41hwzlI3M zz&g2sUBhH?pHO$p7?z)Hs4>+#o!TlVTsmC*TTJJ(Xc7#2fbq8<2zOWsB;sxLfTSpuNU}Q7HgzLB20E)4f$*AGmszaEsOjMJSl-bi2d9j!IBBzTfR`O2)N9J@_wg8V@m}w(CWsW&J z=GZ6nja|GMT~@3{2DUc$dA>v--mcQPt6u4ihR zb;(*K_+|!7C15p*5MRqNZf}Yl-zm0~A@b2`dU2QnW6@@GKKt_J%O_!bf~()b?sJ=1 zGjnqWhK7ChW6_R>s*Se&>XGZJ@V2(Lg!chNM+1OuA5I8peB|SO zM)LE2Q-etie@8!yIFFxyE6>w}{E5aV|2orIr`+@@45m1mBmZ~VCI-G|QLD+9FOJ;>2}XG5bxlSWLERtK(sK5k^E z;HUjEXBV({#QppCxF%IEe;$WkNujOw+S}o?r%+0@noU%<){?7Ao=TXXv(#Bs4|B5I zg9MtX2p8%N_29gcup{GD@pNJML5dS7AdeUo`8VPnJuxxSU80e`(CiLj;jO&s41y2QPnEK>Q8G5q;stF)NL0hwy@j!cqoV?2^0 z95G7I)wN#Z%M3+kAWQmeWTRomycO;hnqVC94B= ze$IMwn9ffH5!vG7X|SrAx7!$!!l$$=M3@Yp9_%7I1veFCySEY9u45EOZTtKQh8mZ? z5BGt~mwtmsu^z|H*0N=Cx{w03wi;g-YEdV>B{(fDtwhLegKMxjBe1cY!v+U6s9Rnp zm)#0zCv<=Frp^)%Fr2LXaISD{F^MMNj^nWsq>#tp=KX_DgHaNf;v_74moz2U)4uw@L^*UQug*An;V)G{#V1H zkGG~KHC6~T&oXOv%XO6^N>z_`o-U(NC1gnSks&zamCtWVztF-)OO z7LT1*zyG2~ebwt2T{%>ScD9(lp<%i=(;?1L6@l2XBP$|hX#8SdDCE|s&Hp&h`>w7| z*sXPoYFYB{K;mmO2E1TWA}OCM)-xGE+7z%rOt+2hyq}|JpFMkKR%fT7BmTXjA|CCW z^X0V%v8`hpQLWFy@8nRsx;~R3Kc=`V$29aaGU9m31KkP)YhoM=QGUwy5cqp;!?KB$ zmC+~?*?$2J$7R`Wf9AU$d~Nfrk$bZ%uye$F71m_wGa!1)K4V|Lk~%RPB(c&zf^^=- z)Hee8Vn};;SZKqGyuiCj213}kNoq8bl=10ML*G7DiCvbzBZZ+|a-CiChrxS~u^taK z>TE|?P;;w@eDaNjc7K8Y5`|9eEi+X@>C9;wY?je|Y46tyvcuD+(sA*QRYbiwu9fnf`XC~7TSCKmTeQ?O$Dmk z_9{M{_M&^LSk+=0DD7m@=cE7>{A5eG|L~k8=fSw%Cl(RUUXA#B+MtW^;~e!HYvjZ= zAJ2fg6b6_=5~jY_QUGYJVn z$k8&$CWCINHufJCq$}z2f;3}S^Y4qDYvz|_vE?7Lz&fuY0^Z=k<$foE44~_J&v03i zZ%L3H#z)LDH^ZLkgTy z_M5UagBOyeH8B0_Z|f4H-Z+|zYoJzFk*Uo3^wOUC*xmg1+E5+5+L9G#c^qNv zkYZH0KO=e#?U{~k6kwf$1MN{Mcv^}y5;Ud9+Ur8qJCHERqZZtHRhJ)Zukmz<7KY7mOSz*#QE-jvU#N0u}_+)}=LP2ecf zXPRe7>A2_ov=8Vg2XS4mQCoR@b`VAhvj>N`D}G}noE0y)=n#8RB1-?80nyAVS0#w8 z!8>Eqq?tP zsE6sfr2NY>3tiTn zzf#;q7oq?qS!n2EF$eCznPAD~Q4d*#7@-~tmPuX0;&#rnn4P+e63jq_HguwIr}2w{ zlvw(0#4%&D6Rqy|&9tS40?|5|;lQ7k#v3zb=4^vEh^4u}re~ zvn8BnLc}m~Yji9FDHz3aosLgI(0*GR47(3h%sea}A;um{>*Ev5BNn^d3XBg})DI!i zx7z5aVS$~ir5Ns9EmKOXDBtO@3*XDycDnnBdI3NvwbR@s%@Qcl!}kZCpBLE;a=7Z7 z|8SSkQq~a4xgdP%xLq9u|L?dS|E_>|Vc%u7Mbze=5)@^b9d~g_p7<4^xQZ!!jj@JW za2;8p`rYKx+8#q)f4gq+u_v>BPz13|Jls(DZVPA{0P7Stu$iIf`S=`}V79PW;jhGfbH)`d|J=Kyuy12_$oYIzHuR1lg4$lB!#W9{rD$&hk{3Nz& zvZ@|-w3${jwQ}s5CWe0Wf1oK2Ql^X~6ae4|J(>&(T}^(&`$c(G_{uZ?5MX0uTJRGqNk66QLv59VQ`(&plZDX}E8jMdn9nf8$|e(P=FNyLPpW6aPJkV?x<{m;a=eVn5k9)FK4EVx`!bS8N;1@ zg!kPkA}4>vRF8s2BQ1pz$2@HYhM)xRA%jD#&`KbqK3cFUngk~%CSqeoEKKXl$+*r} zTOz+=PRR1gV;*|Gd+TZX&o{TtCZt?gX2?^qgI(iU?P#h&GU$Ph>HtPgnYO{H8=8NE+QB zqV+BCv$H}lK~+^%be~P{h9J7PxgSR>KyFxHG-e+N?J($xAD8;?cVe~r_phpkve+{Z z^uWr3)a>-cgYTGCMRi)(H9Qf??sYkWkCDvlr$OBO{ADil)ka1}%n-6vb@oY9SJ%Uu zr~I#4h%@g^&Q4IY{6m62K;Y<0$JY-W8mzR5WKVFNU0r`3yK_(wkR__}twuUrHlCxo zMv?m(+~@c=gGL%ziAz@u3Dbl1T&1}HmUfG>EX4^H={q!ESCUMeFF&jd-(Gtza(H#; z?Ci_}0)mp1Q~s1$G2z7)sT&&$++H2)K0ct(@Q>g7e5&zq=9^(K6T0De_jU6w0u=ZG zg>>>a>~TxaNw{=z=9xk`yH4MSfhkxi2qtNPpx8&2OmKY0$Bzb+rG%Y9mnG1y(2Jv0 zIu-pVFWoq0>4~Qo76LZQ(LAUFt?HRroRy~LXKlNHN3#?~4x!9xRqM)k$UBqQK^jxG zfLWqwHqzcgP_5YqGzoagC{C5In8p;Rd~%0!%nv?lZN0lZlp=1h&bb)o-V^Ubn)VUA zQ^b9*(*W(te}?@9noOF`ZtK~Ve>8^nGNcz7IkB`vYX*nibfDSZY^o;Q1roXRR(t)O zyqIEo7pT8VUi3x({z|LpmPF85l~yP_84LB3f!`rlt2jKS)%Vex9=e3LUZI!nIP<1B zJM$f`F=4yv&1_a(HHnAlFihL*|0GA1Pzd(=)l48-?_P?Ow9#vFTfH3>2t7^ErXC&- ztaOj*H4hhK6@eBC-Gzj}ThY=X-{u6#xvkJFk$RePjg@iS!_*C|o^k=*0ud5E<%cC0 zA^bW1i4?oO3SZsJ_lvw>x5(nrJhMqwg^AJ{SINWD%As;dU*Y=ga<;Cfrpv|{#-M*h zMrW4E*HwCg80vSTf?04c&=)P&g9fXvd>v-dL*3EGLG3Ov+LKt;+1Xk3)5Q*-RQSiR z_3nu0-aBKKk)D-MLB#y}L%ymnvl)Jb?AmY4f2c0n8y6G#kME1!nl@Vi*$^l;J(0PBHn5j93$2gVmo# z;4zv}C#up3$*%H9+)VV~bo0$yyZ#Z$ifFrLqfHz@F9jqh>Ml@-n!1Ip-ap*Zh&V`7 z0I|mklaQ9#e|+Qp&IP|#MfUkPtX1epx)iwXP3RI`+omaN8N}>{RD9=t_Dt9eAaa98 zOm8L2x8jkzdofxXih!Bt;h9qw_kiS z+JdIu+oR@+!b|f4dmi@j^W2gRgkbh5{Ae+3Bd&-UYWbrhdo2 zQ7dR^Dm0Gv#M!XpX*8?_;DRaj%pfMb;_^G8Bmf&`#UvAC$~NK^KNq7|xX|RfoCiCo z9sE7eQc$cN0;hReO6WnRYxf0jXvU-qAM+Y!C0|%kVH$slhl%lsu3t~3AMekXE~-Nn z265P!_zf_eAWkEVA+k(cTU&tl-8HSPH>2^CJlp(G_`Sea&b7u_X}9$>z$S(Q=%oLt zXMB-*U|_4l9UUDV37=KRbp$&48I(Do7X6F-LopD{6cJIxRe&@F<+n8sJqiwm2egJJ zYyQK!rvr6&mERpCG>F6X->P~jFSm4MoxcEWz@Pj#BG{p7$&4Xk=pvJxD-(Q4KWt-V zHPTFobA>IhFFB*mOjlR6RDrqP^H*O$hJt{UIOgX5d>opM7VQ(*qh!txtlC+aa>lX1 zW!l@Ai5APWUpO>gQXo0B^(jb|F_P8LHIp<^HB;{KX8aM|gk3xZpgKa^Mec&^USo*< z;h16Oj1Tf;Aog3T$t?ZO2HYzHGZSDII%VjA*{dwuFX8!*_dClPxWR|EpR(|Eu;puz zLPk?cU!UTG!d#wrkv!d6mWBR{n;%o6P_Z-Dxk+r6N8gx*hOI9;=A-7De+TUo8dbUb zr@|R>UIK88)7ZW~{TlK^3|MlHdZQLj*K1;G+U$ZxPr1d~*Ms;*VQWX)a2lPXNI(F9 zX@Uls-D5A$RY3hbsbwLb8{7t^nMJ+R&s13MZJ1VHBi6AD-@a2i?EqKw2kQ?XOKgO> z2@-}Y8vt3^<)&>PtPR^^4F6yo70G-p3I3C<`tXwy zi?9NUDol_hOVQVHj3a)+8E7=Wpdc;L|9_JrAF=#rhS&)i10>ORq5usQ9p!38>&X8B DJkFbv diff --git a/resources/images/mimetypes/tpz.png b/resources/images/mimetypes/tpz.png new file mode 100644 index 0000000000000000000000000000000000000000..04d685fd2d9f963b4d7dc9d055a23eab365adbae GIT binary patch literal 8372 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 npclM5e_6Xk3hT+35*|q0-6r&;y9~*JAArSONY E-book source format + + Amazon Mobipocket e-book format + + + + + Amazon Topaz ebook format + + + + + Amazon Kindle Application (Kindlet) + + + + + Amazon Mobipocket ebook newspaper format + + + + + + + Amazon KF8 ebook format + + + ''' From 8f62e20b9c07f90bf0140475ed62743b9d09763a Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Fri, 14 Sep 2012 18:08:37 +0200 Subject: [PATCH 4/7] Use the extended APNX content header for KF8 files, FW 3.4 seems to discard the file when the older format is used with a KF8 file... --- src/calibre/devices/kindle/apnx.py | 49 ++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/src/calibre/devices/kindle/apnx.py b/src/calibre/devices/kindle/apnx.py index 4336df81a6..f279efe5a4 100644 --- a/src/calibre/devices/kindle/apnx.py +++ b/src/calibre/devices/kindle/apnx.py @@ -12,7 +12,10 @@ import struct from calibre.ebooks.mobi.reader.mobi6 import MobiReader from calibre.ebooks.pdb.header import PdbHeaderReader +from calibre.ebooks.mobi.reader.headers import MetadataHeader from calibre.utils.logging import default_log +from calibre import prints +from calibre.constants import DEBUG class APNXBuilder(object): ''' @@ -25,12 +28,31 @@ class APNXBuilder(object): pass in a value to page_count, otherwise a count will be estimated using either the fast or accurate algorithm. ''' + import uuid # Check that this is really a MOBI file. with open(mobi_file_path, 'rb') as mf: ident = PdbHeaderReader(mf).identity() if ident != 'BOOKMOBI': raise Exception(_('Not a valid MOBI file. Reports identity of %s') % ident) + # We'll need the PDB name, the MOBI version, and some metadata to make FW 3.4 happy with KF8 files... + apnx_meta = { 'guid': str(uuid.uuid4()).replace('-', '')[:8], 'asin': '', 'cdetype': 'EBOK', 'format': 'MOBI_7', 'acr': '' } + with open(mobi_file_path, 'rb') as mf: + apnx_meta['acr'] = str(PdbHeaderReader(mf).name()) + mh = MetadataHeader(mf, default_log) + if mh.mobi_version == 8: + apnx_meta['format'] = 'MOBI_8' + else: + apnx_meta['format'] = 'MOBI_7' + if mh.exth is None or not mh.exth.cdetype: + apnx_meta['cdetype'] = 'EBOK' + else: + apnx_meta['cdetype'] = str(mh.exth.cdetype) + if mh.exth is None or not mh.exth.uuid: + apnx_meta['asin'] = '' + else: + apnx_meta['asin'] = str(mh.exth.uuid) + # Get the pages depending on the chosen parser pages = [] if page_count: @@ -51,23 +73,32 @@ class APNXBuilder(object): raise Exception(_('Could not generate page mapping.')) # Generate the APNX file from the page mapping. - apnx = self.generate_apnx(pages) + apnx = self.generate_apnx(pages, apnx_meta) # Write the APNX. with open(apnx_path, 'wb') as apnxf: apnxf.write(apnx) - def generate_apnx(self, pages): - import uuid + def generate_apnx(self, pages, apnx_meta): apnx = '' - content_vals = { - 'guid': str(uuid.uuid4()).replace('-', '')[:8], - 'isbn': '', - } + if DEBUG: + prints('APNX META: guid:', apnx_meta['guid']) + prints('APNX META: ASIN:', apnx_meta['asin']) + prints('APNX META: CDE:', apnx_meta['cdetype']) + prints('APNX META: format:', apnx_meta['format']) + prints('APNX META: Name:', apnx_meta['acr']) - content_header = '{"contentGuid":"%(guid)s","asin":"%(isbn)s","cdeType":"EBOK","fileRevisionId":"1"}' % content_vals - page_header = '{"asin":"%(isbn)s","pageMap":"(1,a,1)"}' % content_vals + # Updated header if we have a KF8 file... + if apnx_meta['format'] == 'MOBI_8': + content_header = '{"contentGuid":"%(guid)s","asin":"%(asin)s","cdeType":"%(cdetype)s","format":"%(format)s","fileRevisionId":"1","acr":"%(acr)s"}' % apnx_meta + else: + # My 5.1.x Touch & 3.4 K3 seem to handle the 'extended' header fine for legacy mobi files, too. But, since they still handle this one too, let's try not to break old devices, and keep using the simple header ;). + content_header = '{"contentGuid":"%(guid)s","asin":"%(asin)s","cdeType":"%(cdetype)s","fileRevisionId":"1"}' % apnx_meta + page_header = '{"asin":"%(asin)s","pageMap":"(1,a,1)"}' % apnx_meta + + if DEBUG: + prints('APNX Content Header:', content_header) apnx += struct.pack('>I', 65537) apnx += struct.pack('>I', 12 + len(content_header)) From 11e670e61e2edbd4bdc243c92eecce1430165fa5 Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Fri, 14 Sep 2012 20:50:54 +0200 Subject: [PATCH 5/7] Document the content header changes for the whole APNX/KF8 thing on FW 3.4 --- format_docs/pdb/apnx.txt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/format_docs/pdb/apnx.txt b/format_docs/pdb/apnx.txt index f9feed1da1..8fcba3f029 100644 --- a/format_docs/pdb/apnx.txt +++ b/format_docs/pdb/apnx.txt @@ -9,7 +9,7 @@ the file are big-endian. Layout ------ -bytes content comments +bytes content comments 4 00010001 Format identifier. Value of 65537 little-endian. 4 start of next The offset after ending location of the first header. @@ -25,7 +25,7 @@ Starts next sequence 2 unknown Always 32 N second header String containing the page mapping header 4*N padding The first number given in the page mapping header indicates the number of 0 bytes. -4*N page list +4*N page list Content Header @@ -44,6 +44,14 @@ Example: {"contentGuid":"d8c14b0","asin":"B000JML5VM","cdeType":"EBOK","fileRevisionId":"1296874359405"} +In devices with KF8 support, we're seeing an extended content header (which seems to be required by some FW versions for KF8 files, like FW 3.4): + +format Mobi version. MOBI_8 for KF8, MOBI_7 for legacy mobi files. +acr Palm DB name + +Example: +{"contentGuid":"f2fc7597","asin":"B003M68YKM","cdeType":"EBOK","format":"MOBI_8","fileRevisionId":"1342776186889","acr":"CR!1F5WDHWWVN4Y78MA87Z13H9K6RKE"} + Page Mapping Header ------------------- From 7def8f0b643cf5f586bfa6427665e1f8f9c7cd0e Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Fri, 14 Sep 2012 20:55:02 +0200 Subject: [PATCH 6/7] Delete .han files on Kindle 2/3/Touch, too (linked to KF8 files) --- src/calibre/devices/kindle/driver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/devices/kindle/driver.py b/src/calibre/devices/kindle/driver.py index ac3bcb4bc1..fc3672ccb8 100644 --- a/src/calibre/devices/kindle/driver.py +++ b/src/calibre/devices/kindle/driver.py @@ -289,7 +289,7 @@ class KINDLE2(KINDLE): description = _('Communicate with the Kindle 2/3/4/Touch eBook reader.') FORMATS = ['azw3'] + KINDLE.FORMATS + ['pdf', 'azw4', 'pobi'] - DELETE_EXTS = KINDLE.DELETE_EXTS + ['.mbp1', '.mbs', '.sdr'] + DELETE_EXTS = KINDLE.DELETE_EXTS + ['.mbp1', '.mbs', '.sdr', '.han'] PRODUCT_ID = [0x0002, 0x0004] BCD = [0x0100] From 4296f5c8dbc9bb609dd65e913f02f052d03ebfc7 Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Fri, 14 Sep 2012 21:37:37 +0200 Subject: [PATCH 7/7] More comments on the sidecar folder/files with KF8 files --- src/calibre/devices/kindle/driver.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/calibre/devices/kindle/driver.py b/src/calibre/devices/kindle/driver.py index fc3672ccb8..a657b777f7 100644 --- a/src/calibre/devices/kindle/driver.py +++ b/src/calibre/devices/kindle/driver.py @@ -290,6 +290,7 @@ class KINDLE2(KINDLE): FORMATS = ['azw3'] + KINDLE.FORMATS + ['pdf', 'azw4', 'pobi'] DELETE_EXTS = KINDLE.DELETE_EXTS + ['.mbp1', '.mbs', '.sdr', '.han'] + # On the Touch, there's also .asc files, but not using the same basename (for X-Ray & End Actions), azw3f & azw3r files, but all of them are in the .sdr sidecar folder PRODUCT_ID = [0x0002, 0x0004] BCD = [0x0100]